You are viewing a plain text version of this content. The canonical link for it is here.
Posted to log4j-dev@logging.apache.org by Brian Lind <br...@ecompcon.com> on 2002/10/07 20:43:49 UTC
Re: NTEventLogAppender enhancements [PATCH]
Patch for the afore mentioned bug fixes and enhancements.
------------------------ Cut Here ------------------------
diff -u -N orig/CategorizedMessage.java new/CategorizedMessage.java
--- orig/CategorizedMessage.java Wed Dec 31 18:00:00 1969
+++ new/CategorizedMessage.java Mon Oct 7 13:27:29 2002
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) The Apache Software Foundation. All rights reserved.
+ *
+ * This software is published under the terms of the Apache Software
+ * License version 1.1, a copy of which has been included with this
+ * distribution in the LICENSE.txt file.
+ */
+
+package org.apache.log4j.nt;
+
+import java.beans.*;
+
+/**
+ * Class that allows you to assign a category number to a message to be
+ * logged to the NTEventLogAppender. This category number will show up in
+ * the Category column of the Windows Event Log. If you have text assigned
+ * to those numbers in a resource DLL, you will see the text instead of the
+ * number.
+ *
+ * @author <a href="mailto:brian@ecompcon.com">Brian Lind</a>
+ */
+public class CategorizedMessage extends Object implements java.io.Serializable {
+
+ private PropertyChangeSupport propertySupport;
+
+ /** Holds value of property message. */
+ private Object message;
+
+ /** Holds value of property eventCategory. */
+ private int eventCategory;
+
+ /** Creates new CategorizedMessage */
+ public CategorizedMessage() {
+ propertySupport = new PropertyChangeSupport ( this );
+ }
+
+ /** Creates new CategorizedMessage */
+ public CategorizedMessage(int eventCategory, Object message) {
+ this();
+ this.eventCategory = eventCategory;
+ this.message = message;
+ }
+
+
+ public void addPropertyChangeListener (PropertyChangeListener listener) {
+ propertySupport.addPropertyChangeListener (listener);
+ }
+
+ public void removePropertyChangeListener (PropertyChangeListener listener) {
+ propertySupport.removePropertyChangeListener (listener);
+ }
+
+ /** Getter for property message.
+ * @return Value of property message.
+ */
+ public Object getMessage() {
+ return message;
+ }
+
+ /** Setter for property message.
+ * @param message New value of property message.
+ */
+ public void setMessage(Object message) {
+ this.message = message;
+ }
+
+ /** Getter for property eventCategory.
+ * @return Value of property eventCategory.
+ */
+ public int getEventCategory() {
+ return eventCategory;
+ }
+
+ /** Setter for property eventCategory.
+ * @param eventCategory New value of property eventCategory.
+ */
+ public void setEventCategory(int eventCategory) {
+ this.eventCategory = eventCategory;
+ }
+
+ public java.lang.String toString() {
+ if( message != null )
+ return message.toString();
+ else
+ return "null";
+ }
+
+}
diff -u -N orig/EventLogCategories.mc new/EventLogCategories.mc
--- orig/EventLogCategories.mc Mon Oct 7 13:14:05 2002
+++ new/EventLogCategories.mc Mon Oct 7 13:27:29 2002
@@ -1,20 +1,20 @@
-MessageId=0xC350
+MessageId=1
Language=English
Fatal
.
-MessageId=0x9C40
+MessageId=2
Language=English
Error
.
-MessageId=0x7530
+MessageId=3
Language=English
Warn
.
-MessageId=0x4E20
+MessageId=4
Language=English
Info
.
-MessageId=0x2710
+MessageId=5
Language=English
Debug
.
diff -u -N orig/ExampleCategories.mc new/ExampleCategories.mc
--- orig/ExampleCategories.mc Wed Dec 31 18:00:00 1969
+++ new/ExampleCategories.mc Mon Oct 7 13:27:29 2002
@@ -0,0 +1,44 @@
+MessageId=1
+Language=English
+Fatal
+.
+MessageId=2
+Language=English
+Error
+.
+MessageId=3
+Language=English
+Warn
+.
+MessageId=4
+Language=English
+Info
+.
+MessageId=5
+Language=English
+Debug
+.
+MessageId=6
+Language=English
+Started
+.
+MessageId=7
+Language=English
+Stopped
+.
+MessageId=8
+Language=English
+Success
+.
+MessageId=9
+Language=English
+Failure
+.
+MessageId=10
+Language=English
+Open
+.
+MessageId=11
+Language=English
+Close
+.
diff -u -N orig/ExampleEvents.mc new/ExampleEvents.mc
--- orig/ExampleEvents.mc Wed Dec 31 18:00:00 1969
+++ new/ExampleEvents.mc Mon Oct 7 13:27:29 2002
@@ -0,0 +1,4 @@
+MessageId=0x1000
+Language=English
+Message = (%1)
+.
diff -u -N orig/NTEventLogAppender.java new/NTEventLogAppender.java
--- orig/NTEventLogAppender.java Mon Oct 7 13:14:05 2002
+++ new/NTEventLogAppender.java Mon Oct 7 13:27:29 2002
@@ -26,7 +26,9 @@
will get a java.lang.UnsatisfiedLinkError.
@author <a href="mailto:cstaylor@pacbell.net">Chris Taylor</a>
- @author <a href="mailto:jim_cakalic@na.biomerieux.com">Jim Cakalic</a> */
+ @author <a href="mailto:jim_cakalic@na.biomerieux.com">Jim Cakalic</a>
+ @author <a href="mailto:brian@ecompcon.com">Brian Lind</a>
+ */
public class NTEventLogAppender extends AppenderSkeleton {
private int _handle = 0;
@@ -58,8 +60,18 @@
public NTEventLogAppender(String source, Layout layout) {
this(null, source, layout);
}
-
+
public NTEventLogAppender(String server, String source, Layout layout) {
+ this(server, source, layout, null, null);
+ }
+
+ public NTEventLogAppender(String server, String source, Layout layout,
+ String categoryMessageFile) {
+ this(server, source, layout, categoryMessageFile, null);
+ }
+
+ public NTEventLogAppender(String server, String source, Layout layout,
+ String categoryMessageFile, String eventMessageFile) {
if (source == null) {
source = "Log4j";
}
@@ -70,6 +82,10 @@
}
try {
+ if( categoryMessageFile != null )
+ setCategoryMessageFile(categoryMessageFile);
+ if( eventMessageFile != null )
+ setEventMessageFile(eventMessageFile);
_handle = registerEventSource(server, source);
} catch (Exception e) {
e.printStackTrace();
@@ -109,14 +125,20 @@
}
}
}
- // Normalize the log message level into the supported categories
- int nt_category = event.level.toInt();
+ // Normalize the log message level into the supported NT event types
+ int priority = event.level.toInt();
// Anything above FATAL or below DEBUG is labeled as INFO.
- //if (nt_category > FATAL || nt_category < DEBUG) {
- // nt_category = INFO;
+ //if (priority > FATAL || priority < DEBUG) {
+ // priority = INFO;
//}
- reportEvent(_handle, sbuf.toString(), nt_category);
+ if( event.getMessage() instanceof CategorizedMessage ) {
+ CategorizedMessage extendedMsg = (CategorizedMessage)(event.getMessage());
+ reportEventAndCategory(_handle, sbuf.toString(), priority, extendedMsg.getEventCategory());
+ }
+ else {
+ reportEvent(_handle, sbuf.toString(), priority);
+ }
}
@@ -149,9 +171,16 @@
}
native private int registerEventSource(String server, String source);
- native private void reportEvent(int handle, String message, int level);
+ native private void reportEvent(int handle, String message, int priority);
native private void deregisterEventSource(int handle);
+ native private void setEventMessageFile(String dllName);
+ native private void setCategoryMessageFile(String dllName);
+ native private void reportEventAndCategory(int handle, String message, int priority, int category);
+
+ native public boolean isUserDisplayed();
+ native public void setUserDisplayed(boolean on);
+
static {
System.loadLibrary("NTEventLogAppender");
}
diff -u -N orig/Notes.txt new/Notes.txt
--- orig/Notes.txt Wed Dec 31 18:00:00 1969
+++ new/Notes.txt Mon Oct 7 13:27:29 2002
@@ -0,0 +1,36 @@
+Notes:
+
+The NTEventLogAppender.dll DLL still needs to be found in your PATH, even if
+you use custom resource only DLL's. Your resource DLL's, of course, need to
+be found in the PATH somewhere too.
+
+
+When creating your own resource only DLL for your custom categories, you should
+still include the standard log4j ones for compatability purposes. You can copy
+and paste the standard ones (number 1 thru 5) from the EventLogCategories.mc file.
+Be sure to start numbering yours at 6 on up or they will not show up in the Event Log.
+If you leave gaps in the numbers, only the numbers show up in the Event Log instead
+of the text. At least that's what I've experienced when I decided to try and start
+numbering my categories at 100. Didn't work for me.
+
+To use custom categories you need to tell the NTEventLogAppender about you custom
+resource only DLL and use the CategorizedMessage class to associate a category
+number with you log message.
+Example:
+
+ Category log = Category.getInstance(appName);
+ NTEventLogAppender appender =
+ new NTEventLogAppender(null, appName, null, "MyCategories.dll");
+ log.addAppender(appender);
+ log.info(new CategorizedMessage(6, "Hi there."));
+
+
+If you would like to use a custom event, not very useful at this point, you
+can create a resource only DLL message file (.mc file), with one message
+in it with MessageId=0x1000 and whatever you want for the text of the event.
+If you don't include a %1 somewhere in the text, you'll never see the message you
+passed in from Java. You specify your event message DLL in a NTEventLogAppender
+contructor.
+Example:
+ NTEventLogAppender appender =
+ new NTEventLogAppender(null, appName, null, "MyCategories.dll", "MyEvent.dll");
diff -u -N orig/examplemake.bat new/examplemake.bat
--- orig/examplemake.bat Wed Dec 31 18:00:00 1969
+++ new/examplemake.bat Mon Oct 7 13:27:29 2002
@@ -0,0 +1,12 @@
+@echo off
+
+REM Example for creating custom Event Categories and Event ID's and descriptions
+
+MC ExampleCategories.mc
+RC -r -fo ExampleCategories.res ExampleCategories.rc
+LINK /subsystem:windows /INCREMENTAL:NO /dll /noentry /out:"ExampleCategories.dll" ExampleCategories.res
+
+MC ExampleEvents.mc
+RC -r -fo ExampleEvents.res ExampleEvents.rc
+LINK /subsystem:windows /INCREMENTAL:NO /dll /noentry /out:"ExampleEvents.dll" ExampleEvents.res
+
diff -u -N orig/nteventlog.cpp new/nteventlog.cpp
--- orig/nteventlog.cpp Mon Oct 7 13:14:06 2002
+++ new/nteventlog.cpp Mon Oct 7 13:36:11 2002
@@ -12,6 +12,12 @@
#include "org_apache_log4j_nt_NTEventLogAppender.h"
#include <windows.h>
+const DWORD defaultMessageID = 0x1000;
+DWORD messageID = defaultMessageID;
+char *EventMessageFile = "NTEventLogAppender.dll";
+char *CategoryMessageFile = "NTEventLogAppender.dll";
+BOOL displayUser = FALSE;
+
// Borrowed unabashedly from the JNI Programmer's Guide
void JNU_ThrowByName(JNIEnv *env, const char *name, const char *msg) {
@@ -83,8 +89,27 @@
* be displayed in the NT Event Viewer.
*/
WORD getCategory(jint priority) {
- // Priority values map directly to EventLog category values
- return (WORD)(priority + 1);
+ WORD ret_val = 0;
+
+ // Map priority to a resonable category name code from EvengLogCategories.mc
+ switch (priority) {
+ case org_apache_log4j_Priority_FATAL_INT:
+ ret_val = 1;
+ break;
+ case org_apache_log4j_Priority_ERROR_INT:
+ ret_val = 2;
+ break;
+ case org_apache_log4j_Priority_WARN_INT:
+ ret_val = 3;
+ break;
+ case org_apache_log4j_Priority_INFO_INT:
+ ret_val = 4;
+ break;
+ case org_apache_log4j_Priority_DEBUG_INT:
+ ret_val = 5;
+ break;
+ }
+ return ret_val;
}
/*
@@ -112,12 +137,13 @@
return ret_val;
}
-HKEY regGetKey(TCHAR *subkey, DWORD *disposition) {
- HKEY hkey = 0;
- RegCreateKeyEx(HKEY_LOCAL_MACHINE, subkey, 0, NULL,
- REG_OPTION_NON_VOLATILE, KEY_SET_VALUE, NULL,
- &hkey, disposition);
- return hkey;
+DWORD regGetKey(TCHAR *subkey, HKEY *hkey) {
+ DWORD result;
+ DWORD disposition;
+ result = RegCreateKeyEx(HKEY_LOCAL_MACHINE, subkey, 0, NULL,
+ REG_OPTION_NON_VOLATILE, KEY_SET_VALUE, NULL,
+ hkey, &disposition);
+ return result;
}
void regSetString(HKEY hkey, TCHAR *name, TCHAR *value) {
@@ -133,28 +159,51 @@
*/
void addRegistryInfo(char *source) {
const TCHAR *prefix = "SYSTEM\\CurrentControlSet\\Services\\EventLog\\Application\\";
- DWORD disposition;
+ DWORD result;
HKEY hkey = 0;
TCHAR subkey[256];
lstrcpy(subkey, prefix);
lstrcat(subkey, source);
- hkey = regGetKey(subkey, &disposition);
- if (disposition == REG_CREATED_NEW_KEY) {
- regSetString(hkey, "EventMessageFile", "NTEventLogAppender.dll");
- regSetString(hkey, "CategoryMessageFile", "NTEventLogAppender.dll");
+ result = regGetKey(subkey, &hkey);
+ if (result == ERROR_SUCCESS) {
+ regSetString(hkey, "EventMessageFile", EventMessageFile);
+ regSetString(hkey, "CategoryMessageFile", CategoryMessageFile);
regSetDword(hkey, "TypesSupported", (DWORD)7);
- regSetDword(hkey, "CategoryCount", (DWORD)8);
+ regSetDword(hkey, "CategoryCount", (DWORD)1000);
}
- //RegSetValueEx(hkey, "EventMessageFile", 0, REG_SZ, (LPBYTE)dllname, lstrlen(dllname));
- //RegSetValueEx(hkey, "CategoryMessageFile", 0, REG_SZ, (LPBYTE)dllname, lstrlen(dllname));
- //RegSetValueEx(hkey, "TypesSupported", 0, REG_DWORD, (LPBYTE)&whichTypes, sizeof(DWORD));
- //RegSetValueEx(hkey, "CategoryCount", 0, REG_DWORD, (LPBYTE)&numCategories, sizeof(DWORD));
RegCloseKey(hkey);
return;
}
/*
+ * Lookup the current user's SID and return a pointer to it
+ */
+PSID getCurrentUserId()
+{
+ char user[256];
+ DWORD userLen = 256;
+ PSID userSidPtr = NULL;
+ DWORD sidLen = 0;
+ char domain[256];
+ DWORD domainLen = sizeof(domain);
+ SID_NAME_USE accountType;
+ if( GetUserName(user, &userLen) )
+ {
+ LookupAccountName(NULL, user, userSidPtr, &sidLen,
+ domain, &domainLen, &accountType);
+ userSidPtr = (SID *)malloc(sidLen);
+ if( ! LookupAccountName(NULL, user, userSidPtr, &sidLen,
+ domain, &domainLen, &accountType) )
+ {
+ free(userSidPtr);
+ userSidPtr = NULL;
+ }
+ }
+ return userSidPtr;
+}
+
+/*
* Class: org.apache.log4j.nt.NTEventLogAppender
* Method: registerEventSource
* Signature: (Ljava/lang/String;Ljava/lang/String;)I
@@ -184,8 +233,40 @@
* Signature: (ILjava/lang/String;I)V
*/
JNIEXPORT void JNICALL Java_org_apache_log4j_nt_NTEventLogAppender_reportEvent(
- JNIEnv *env, jobject java_this, jint handle, jstring jstr, jint priority) {
-
+ JNIEnv *env, jobject java_this, jint handle, jstring jstr, jint priority)
+{
+ Java_org_apache_log4j_nt_NTEventLogAppender_reportEventAndCategory(
+ env, java_this, handle, jstr, priority, getCategory(priority));
+ return;
+}
+
+/*
+ * Class: org_apache_log4j_nt_NTEventLogAppender
+ * Method: deregisterEventSource
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL Java_org_apache_log4j_nt_NTEventLogAppender_deregisterEventSource(
+JNIEnv *env,
+jobject java_this,
+jint handle)
+{
+ DeregisterEventSource((HANDLE)handle);
+}
+
+
+/*
+ * Class: org_apache_log4j_nt_NTEventLogAppender
+ * Method: reportEvent
+ * Signature: (ILjava/lang/String;II)V
+ */
+JNIEXPORT void JNICALL Java_org_apache_log4j_nt_NTEventLogAppender_reportEventAndCategory
+ (JNIEnv *env,
+ jobject java_this,
+ jint handle,
+ jstring jstr,
+ jint priority,
+ jint category)
+{
jboolean localHandle = JNI_FALSE;
if (handle == 0) {
// Client didn't give us a handle so make a local one.
@@ -199,15 +280,24 @@
char *nstr = JNU_GetStringNativeChars(env, jstr);
array[0] = nstr;
+ // lookup user
+ PSID userSidPtr = NULL;
+ if( displayUser )
+ userSidPtr = getCurrentUserId();
+
// This is the only message supported by the package. It is backed by
// a message resource which consists of just '%1' which is replaced
// by the string we just created.
- const DWORD messageID = 0x1000;
- ReportEvent((HANDLE)handle, getType(priority),
- getCategory(priority),
- messageID, NULL, 1, 0, array, NULL);
+ ReportEvent((HANDLE)handle, getType(priority), (WORD)category,
+ defaultMessageID, userSidPtr, 1, 0, array, NULL);
free((void *)nstr);
+
+ if( userSidPtr != NULL )
+ {
+ free(userSidPtr);
+ }
+
if (localHandle == JNI_TRUE) {
// Created the handle here so free it here too.
DeregisterEventSource((HANDLE)handle);
@@ -217,16 +307,66 @@
/*
* Class: org_apache_log4j_nt_NTEventLogAppender
- * Method: deregisterEventSource
- * Signature: (I)V
+ * Method: isUserDisplayed
+ * Signature: ()Z
*/
-JNIEXPORT void JNICALL Java_org_apache_log4j_nt_NTEventLogAppender_deregisterEventSource(
-JNIEnv *env,
-jobject java_this,
-jint handle)
+JNIEXPORT jboolean JNICALL Java_org_apache_log4j_nt_NTEventLogAppender_isUserDisplayed
+ (JNIEnv *env,
+ jobject java_this)
{
- DeregisterEventSource((HANDLE)handle);
+ if( displayUser )
+ return JNI_TRUE;
+ return JNI_FALSE;
}
+/*
+ * Class: org_apache_log4j_nt_NTEventLogAppender
+ * Method: setUserDisplayed
+ * Signature: (Z)V
+ */
+JNIEXPORT void JNICALL Java_org_apache_log4j_nt_NTEventLogAppender_setUserDisplayed
+ (JNIEnv *env,
+ jobject java_this,
+ jboolean on)
+{
+ if( on == JNI_TRUE )
+ displayUser = TRUE;
+ else
+ displayUser = FALSE;
+}
+
+/*
+ * Class: org_apache_log4j_nt_NTEventLogAppender
+ * Method: setEventMessageFile
+ * Signature: (Ljava/lang/String;)V
+ */
+JNIEXPORT void JNICALL Java_org_apache_log4j_nt_NTEventLogAppender_setEventMessageFile
+ (JNIEnv *env,
+ jobject java_this,
+ jstring dllName)
+{
+ char *nstr = JNU_GetStringNativeChars(env, dllName);
+ if( nstr != NULL && strlen(nstr) > 0 )
+ {
+ EventMessageFile = (char *)strdup(nstr);
+ }
+}
+
+/*
+ * Class: org_apache_log4j_nt_NTEventLogAppender
+ * Method: setCategoryMessageFile
+ * Signature: (Ljava/lang/String;)V
+ */
+JNIEXPORT void JNICALL Java_org_apache_log4j_nt_NTEventLogAppender_setCategoryMessageFile
+ (JNIEnv *env,
+ jobject java_this,
+ jstring dllName)
+{
+ char *nstr = JNU_GetStringNativeChars(env, dllName);
+ if( nstr != NULL && strlen(nstr) > 0 )
+ {
+ CategoryMessageFile = (char *)strdup(nstr);
+ }
+}
#endif
--
To unsubscribe, e-mail: <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>