$search
00001 /* 00002 * NTEventLogAppender.cpp 00003 */ 00004 00005 #ifdef WIN32 // only available on Win32 00006 00007 #include <log4cpp/NTEventLogAppender.hh> 00008 #include <log4cpp/FactoryParams.hh> 00009 #include <memory> 00010 00011 namespace log4cpp { 00012 00013 NTEventLogAppender::NTEventLogAppender(const std::string& name, const std::string& sourceName) : 00014 AppenderSkeleton(name), 00015 _strSourceName(sourceName), 00016 _hEventSource(NULL) 00017 { 00018 open(); 00019 } 00020 00021 NTEventLogAppender::~NTEventLogAppender() 00022 { 00023 close(); 00024 } 00025 00026 void NTEventLogAppender::open() 00027 { 00028 addRegistryInfo(_strSourceName.c_str()); 00029 _hEventSource = ::RegisterEventSource(NULL, _strSourceName.c_str()); 00030 } 00031 00032 void NTEventLogAppender::close() 00033 { 00034 if (_hEventSource) { 00035 ::DeregisterEventSource(_hEventSource); 00036 } 00037 } 00038 00039 bool NTEventLogAppender::reopen() { 00040 close(); 00041 open(); 00042 return true; 00043 } 00044 00045 bool NTEventLogAppender::requiresLayout() const { 00046 return false; 00047 } 00048 00049 void NTEventLogAppender::setLayout(Layout* layout) { 00050 return; 00051 } 00052 00053 void NTEventLogAppender::_append(const LoggingEvent& event) { 00054 const char* ps[1]; 00055 ps[0] = event.message.c_str(); 00056 00057 const DWORD messageID = 0x1000; 00058 ::ReportEvent(_hEventSource, getType(event.priority), 00059 getCategory(event.priority), 00060 messageID, NULL, 1, 0, ps, NULL); 00061 } 00062 00068 WORD NTEventLogAppender::getCategory(Priority::Value priority) { 00069 // Priority values map directly to EventLog category values 00070 return (WORD)((priority / 100) + 1); 00071 } 00072 00078 WORD NTEventLogAppender::getType(Priority::Value priority) { 00079 00080 WORD ret_val; 00081 00082 switch (priority) { 00083 case Priority::EMERG: 00084 // FATAL is the same value as EMERG 00085 // case Priority::FATAL: 00086 case Priority::ALERT: 00087 case Priority::CRIT: 00088 case Priority::ERROR: 00089 ret_val = EVENTLOG_ERROR_TYPE; 00090 break; 00091 case Priority::WARN: 00092 ret_val = EVENTLOG_WARNING_TYPE; 00093 break; 00094 case Priority::NOTICE: 00095 case Priority::INFO: 00096 case Priority::DEBUG: 00097 default: 00098 ret_val = EVENTLOG_INFORMATION_TYPE; 00099 break; 00100 } 00101 return ret_val; 00102 } 00103 00104 HKEY NTEventLogAppender::regGetKey(TCHAR *subkey, DWORD *disposition) { 00105 HKEY hkey = 0; 00106 RegCreateKeyEx(HKEY_LOCAL_MACHINE, subkey, 0, NULL, 00107 REG_OPTION_NON_VOLATILE, KEY_SET_VALUE, NULL, 00108 &hkey, disposition); 00109 return hkey; 00110 } 00111 00112 void NTEventLogAppender::regSetString(HKEY hkey, TCHAR *name, TCHAR *value) { 00113 RegSetValueEx(hkey, name, 0, REG_SZ, (LPBYTE)value, lstrlen(value)); 00114 } 00115 00116 void NTEventLogAppender::regSetDword(HKEY hkey, TCHAR *name, DWORD value) { 00117 RegSetValueEx(hkey, name, 0, REG_DWORD, (LPBYTE)&value, sizeof(DWORD)); 00118 } 00119 00120 /* 00121 * Add this source with appropriate configuration keys to the registry. 00122 */ 00123 void NTEventLogAppender::addRegistryInfo(const char *source) { 00124 const TCHAR *prefix = "SYSTEM\\CurrentControlSet\\Services\\EventLog\\Application\\"; 00125 DWORD disposition; 00126 HKEY hkey = 0; 00127 TCHAR subkey[256]; 00128 00129 lstrcpy(subkey, prefix); 00130 lstrcat(subkey, source); 00131 hkey = regGetKey(subkey, &disposition); 00132 if (disposition == REG_CREATED_NEW_KEY) { 00133 regSetString(hkey, "EventMessageFile", "NTEventLogAppender.dll"); 00134 regSetString(hkey, "CategoryMessageFile", "NTEventLogAppender.dll"); 00135 regSetDword(hkey, "TypesSupported", (DWORD)7); 00136 regSetDword(hkey, "CategoryCount", (DWORD)8); 00137 } 00138 RegCloseKey(hkey); 00139 return; 00140 } 00141 00142 std::auto_ptr<Appender> create_nt_event_log_appender(const FactoryParams& params) 00143 { 00144 std::string name, source_name; 00145 params.get_for("nt event log appender").required("name", name)("source_name", source_name); 00146 00147 return std::auto_ptr<Appender>(new NTEventLogAppender(name, source_name)); 00148 } 00149 } 00150 00151 #endif // WIN32