summaryrefslogtreecommitdiffstats
path: root/pki/base/osutil/src/com/netscape/osutil/NTEventLogger.java
blob: 0002db87a74d51e10dd8f2052e8b758a4ecff0e7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
// --- BEGIN COPYRIGHT BLOCK ---
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; version 2 of the License.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with this program; if not, write to the Free Software Foundation, Inc.,
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
//
// (C) 2007 Red Hat, Inc.
// All rights reserved.
// --- END COPYRIGHT BLOCK ---
package com.netscape.osutil;


/**
 * This class provides an interface to Windows NT event logging.
 *
 * @version $Revision$, $Date$
 */
public class NTEventLogger {

    private byte[] handle; // Must be non-null. Should be non-empty.
    private boolean open; // true if this log is open for writing.

    // The Windows NT event ID.  The actual event ID is 1001, but we also
    // need to set bit 29 to indicate that we are not Microsoft.
    // See _Windows NT Event Logging_ (O'Reilly), page 128, for an explanation.
    public static final int EVENT_ID = 0x20000000 | 1001;

    private NTEventLogger() {
    }

    // Load native library.  This is the same library used by OsSubsystem.
    // loadLibrary() is idempotent, so don't worry about calling it multiple
    // times.
    static {
        boolean mNativeLibrariesLoaded = false;
        String os = System.getProperty( "os.name" );
        if( ( os.equals( "Linux" ) ) ) {
            // Check for 64-bit library availability
            // prior to 32-bit library availability.
            mNativeLibrariesLoaded =
                OSUtil.tryLoad( "/usr/lib64/osutil/libosutil.so" );
            if( mNativeLibrariesLoaded ) {
                System.out.println( "64-bit osutil library loaded" );
            } else {
                // REMINDER:  May be trying to run a 32-bit app
                //            on 64-bit platform.
                mNativeLibrariesLoaded =
                    OSUtil.tryLoad( "/usr/lib/osutil/libosutil.so" );
                if( mNativeLibrariesLoaded ) {
                    System.out.println( "32-bit osutil library loaded");
                } else {
                    System.out.println( "FAILED loading osutil library!");
                    System.exit( -1 );
                }
            }
        } else {
            try {
                System.loadLibrary( "osutil" );
                System.out.println( "osutil library loaded" );
                mNativeLibrariesLoaded = true;
            } catch( Throwable t ) {
                // This is bad news, the program is doomed at this point
                t.printStackTrace();
            }
        }
    }

    /**
     * Creates an application or system NT Event log handle.
     *
     * @param eventSourceName The name of the source application.
     *    This should be a subkey of
     *    <code>HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\EventLog</code>.
     *    If the given source does not exist, NT will automatically return
     *        a handle to the application log without complaining.
     *    The reason to use a real source, rather than just using the default
     *        application log, is that the registry key of a real source
     *        tells NT where to find the message resources for formatting
     *        the strings that are sent in <code>reportEvent</code>.
     *        If the default application log is used, NT will insert a lame
     *        message: "The description for Event ID ( ... ) in Source
     *        ( ... ) could not be found. It contains the following insertion
     *        string(s):".
     * @throws Exception If an error occurs in the native NT code.  The
     *    exception message will contain more information.
     */
    public NTEventLogger(String eventSourceName) throws Exception {
        open = true;
        handle = initNTLog(eventSourceName);
    }

    /**
     * Writes a string to the log.  This is the simple way to write to the
     *  NT event log.
     *    <p>This method must not be called after the log is
     *    closed.
     * 
     * @param type The type of the event that is logged.  Pre-defined types
     *         are:
     *    <table border>
     *    <tr><th>Name</th><th>Description</th></tr>
     *    <tr><td>EVENTLOG_SUCCESS</td><td>Success</td></tr>
     *    <tr><td>EVENTLOG_ERROR_TYPE</td><td>Error</td></tr>
     *    <tr><td>EVENTLOG_WARNING_TYPE</td><td>Warning</td></tr>
     *    <tr><td>EVENTLOG_INFORMATION_TYPE</td><td>Informational</td></tr>
     *    <tr><td>EVENTLOG_AUDIT_SUCCESS</td><td>Success Audit</td></tr>
     *    <tr><td>EVENTLOG_AUDIT_FAILURE</td><td>Failure Audit</td></tr>
     *    </table>
     * @param logMessage The string that will be written to the log.
     * @exception Exception If an error occurs. The exception message will
     *        have more information.
     */
    public void
    reportEvent(int type, String logMessage) throws Exception {
        if (!open) {
            throw new IllegalArgumentException("Log has been closed");
        }

        reportEventNative(handle, (short) type, (short) 0, EVENT_ID,
            new String[] {logMessage}
        );
    }

    /**
     * Writes an NT event to the log.  See NT documentation for a description
     * of the parameters. This is the complicated way to write to the log,
     *    to be used if you want to do something tricky. Normally you'll want
     *    to call reportEvent(int, String).
     *    <p>This method must not be called after the log is
     *    closed.
     * 
     * @param type The type of the event that is logged.  Pre-defined types
     *         are:
     *    <table border>
     *    <tr><th>Name</th><th>Description</th></tr>
     *    <tr><td>EVENTLOG_SUCCESS</td><td>Success</td></tr>
     *    <tr><td>EVENTLOG_ERROR_TYPE</td><td>Error</td></tr>
     *    <tr><td>EVENTLOG_WARNING_TYPE</td><td>Warning</td></tr>
     *    <tr><td>EVENTLOG_INFORMATION_TYPE</td><td>Informational</td></tr>
     *    <tr><td>EVENTLOG_AUDIT_SUCCESS</td><td>Success Audit</td></tr>
     *    <tr><td>EVENTLOG_AUDIT_FAILURE</td><td>Failure Audit</td></tr>
     *    </table>
     * @param category An application-defined category for the event, which
     *        must be in the range 0-65535. A value of 0 indicates that there
     *        is not event category.
     * @param eventID The application-specific event index.  It must be in the
     *        range 0-65535.
     * @param strings An array of description strings to be written to the log.
     * @exception Exception If an error occurs. The exception message will
     *        have more information.
     */
    public void
    reportEvent(int type, int category, int eventID,
        String[] strings) throws Exception {
        if (!open) {
            throw new IllegalArgumentException("Log has been closed");
        }

        /* check args */
        if (category < 0 || category > 65535) {
            throw new IllegalArgumentException("category " + category +
                    " is outside the valid range");
        }

        reportEventNative(handle, (short) type, (short) category,
            eventID, strings);
    }

    private static native void
    reportEventNative(byte[] handle, short type, short category, int eventID,
        String[] strings) throws Exception;

    // Cleans up native resources when the Java object gets garbage collected
    protected void finalize() throws Throwable {
        close();
    }

    public void close() throws Exception {
        if (open) {
            shutdownNTLog(handle);
            open = false;
        }
    }
    
    // creates the NT log in native code, returns a byte array containing
    // the Windows log HANDLE.
    private static native byte[]
    initNTLog(String eventSourceName) throws Exception;

    // Closes the log pointed to by the given handle.
    private static native void
    shutdownNTLog(byte[] handle) throws Exception;

    public static void main(String args[]) {
        try {
            NTEventLogger h = new NTEventLogger("NTEventLogger test");

            h.reportEvent(EVENTLOG_SUCCESS, "This is a test");
            h.reportEvent(EVENTLOG_ERROR_TYPE,
                "SERVER MELTDOWN: Evacuate the building!!!");

        }catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static final short EVENTLOG_SUCCESS = 0;
    public static final short EVENTLOG_ERROR_TYPE = 1;
    public static final short EVENTLOG_WARNING_TYPE = 2;
    public static final short EVENTLOG_INFORMATION_TYPE = 4;
    public static final short EVENTLOG_AUDIT_SUCCESS = 8;
    public static final short EVENTLOG_AUDIT_FAILURE = 16;
}