Come accedere ai dati del registro di Visualizzatore eventi di Windows da Java

C’è un modo per accedere al registro eventi di Windows da una class java. Qualcuno ha scritto qualche API per questo e ci sarebbe stato un modo per accedere ai dati da una macchina remota?

Lo scenario è:

Eseguo un processo su una macchina remota, da un processo Java di controllo. Questo processo remoto registra le cose nel registro eventi, che voglio essere in grado di vedere nel processo di controllo.

Grazie in anticipo.

Sul lato Java, avrai bisogno di una libreria che ti permetta di effettuare chiamate native. Sun offre JNI , ma suona come una specie di dolore. Considera anche:

Sul lato Windows, la funzione che stai cercando è OpenEventLog . Questo dovrebbe consentire di accedere a un registro eventi remoto. Vedi anche Interrogazione per informazioni sull’evento .

Se ciò non suona bene, ho anche trovato questo per analizzare direttamente i file di log (non un approccio che raccomanderei ma comunque interessante):

http://www.j-interop.org/ è una libreria Java open source che implementa le specifiche del protocollo DCOM senza utilizzare alcun codice nativo . (cioè puoi usarlo per accedere agli oggetti DCOM su un host Windows remoto da codice Java in esecuzione su un client non Windows).

Microsoft espone una pletora di informazioni di sistema tramite Windows Management Instrumentation (WMI). WMI è accessibile da remoto tramite DCOM e sul sito di Microsoft esiste una notevole documentazione sull’argomento. Come succede, puoi accedere ai registri eventi di Windows tramite questa interfaccia accessibile a distanza.

Utilizzando j-interop è ansible creare un’istanza dell’object WMI WbemScripting.SWbemLocator in remoto, quindi connettersi ai servizi WMI (Windows Management Instrumentation) sull’host Windows remoto. Da lì è ansible inviare una query che ti informsrà ogni volta che viene scritta una nuova voce del registro eventi.

Notare che ciò richiede che DCOM sia abilitato e configurato correttamente nell’host remoto di Windows e che siano state impostate eccezioni appropriate in qualsiasi firewall. Dettagli su questo possono essere cercati online, e sono anche referenziati dal sito j-interop, sopra.

L’esempio seguente si connette a un host remoto utilizzando il dominio NT, il nome host, un nome utente e una password e si trova in un ciclo, scaricando ogni voce del registro eventi quando vengono registrati da Windows. All’utente devono essere state concesse le autorizzazioni di accesso DCOM remote appropriate, ma non deve essere un amministratore.

import java.io.IOException; import java.util.logging.Level; import org.jinterop.dcom.common.JIException; import org.jinterop.dcom.common.JISystem; import org.jinterop.dcom.core.JIComServer; import org.jinterop.dcom.core.JIProgId; import org.jinterop.dcom.core.JISession; import org.jinterop.dcom.core.JIString; import org.jinterop.dcom.core.JIVariant; import org.jinterop.dcom.impls.JIObjectFactory; import org.jinterop.dcom.impls.automation.IJIDispatch; public class EventLogListener { private static final String WMI_DEFAULT_NAMESPACE = "ROOT\\CIMV2"; private static JISession configAndConnectDCom( String domain, String user, String pass ) throws Exception { JISystem.getLogger().setLevel( Level.OFF ); try { JISystem.setInBuiltLogHandler( false ); } catch ( IOException ignored ) { ; } JISystem.setAutoRegisteration( true ); JISession dcomSession = JISession.createSession( domain, user, pass ); dcomSession.useSessionSecurity( true ); return dcomSession; } private static IJIDispatch getWmiLocator( String host, JISession dcomSession ) throws Exception { JIComServer wbemLocatorComObj = new JIComServer( JIProgId.valueOf( "WbemScripting.SWbemLocator" ), host, dcomSession ); return (IJIDispatch) JIObjectFactory.narrowObject( wbemLocatorComObj.createInstance().queryInterface( IJIDispatch.IID ) ); } private static IJIDispatch toIDispatch( JIVariant comObjectAsVariant ) throws JIException { return (IJIDispatch) JIObjectFactory.narrowObject( comObjectAsVariant.getObjectAsComObject() ); } public static void main( String[] args ) { if ( args.length != 4 ) { System.out.println( "Usage: " + EventLogListener.class.getSimpleName() + " domain host username password" ); return; } String domain = args[ 0 ]; String host = args[ 1 ]; String user = args[ 2 ]; String pass = args[ 3 ]; JISession dcomSession = null; try { // Connect to DCOM on the remote system, and create an instance of the WbemScripting.SWbemLocator object to talk to WMI. dcomSession = configAndConnectDCom( domain, user, pass ); IJIDispatch wbemLocator = getWmiLocator( host, dcomSession ); // Invoke the "ConnectServer" method on the SWbemLocator object via it's IDispatch COM pointer. We will connect to // the default ROOT\CIMV2 namespace. This will result in us having a reference to a "SWbemServices" object. JIVariant results[] = wbemLocator.callMethodA( "ConnectServer", new Object[] { new JIString( host ), new JIString( WMI_DEFAULT_NAMESPACE ), JIVariant.OPTIONAL_PARAM(), JIVariant.OPTIONAL_PARAM(), JIVariant.OPTIONAL_PARAM(), JIVariant.OPTIONAL_PARAM(), new Integer( 0 ), JIVariant.OPTIONAL_PARAM() } ); IJIDispatch wbemServices = toIDispatch( results[ 0 ] ); // Now that we have a SWbemServices DCOM object reference, we prepare a WMI Query Language (WQL) request to be informsd whenever a // new instance of the "Win32_NTLogEvent" WMI class is created on the remote host. This is submitted to the remote host via the // "ExecNotificationQuery" method on SWbemServices. This gives us all events as they come in. Refer to WQL documentation to // learn how to restrict the query if you want a narrower focus. final String QUERY_FOR_ALL_LOG_EVENTS = "SELECT * FROM __InstanceCreationEvent WHERE TargetInstance ISA 'Win32_NTLogEvent'"; final int RETURN_IMMEDIATE = 16; final int FORWARD_ONLY = 32; JIVariant[] eventSourceSet = wbemServices.callMethodA( "ExecNotificationQuery", new Object[] { new JIString( QUERY_FOR_ALL_LOG_EVENTS ), new JIString( "WQL" ), new JIVariant( new Integer( RETURN_IMMEDIATE + FORWARD_ONLY ) ) } ); IJIDispatch wbemEventSource = (IJIDispatch) JIObjectFactory.narrowObject( ( eventSourceSet[ 0 ] ).getObjectAsComObject() ); // The result of the query is a SWbemEventSource object. This object exposes a method that we can call in a loop to retrieve the // next Windows Event Log entry whenever it is created. This "NextEvent" operation will block until we are given an event. // Note that you can specify timeouts, see the Microsoft documentation for more details. while ( true ) { // this blocks until an event log entry appears. JIVariant eventAsVariant = (JIVariant) ( wbemEventSource.callMethodA( "NextEvent", new Object[] { JIVariant.OPTIONAL_PARAM() } ) )[ 0 ]; IJIDispatch wbemEvent = toIDispatch( eventAsVariant ); // WMI gives us events as SWbemObject instances (a base class of any WMI object). We know in our case we asked for a specific object // type, so we will go ahead and invoke methods supported by that Win32_NTLogEvent class via the wbemEvent IDispatch pointer. // In this case, we simply call the "GetObjectText_" method that returns us the entire object as a CIM formatted string. We could, // however, ask the object for its property values via wbemEvent.get("PropertyName"). See the j-interop documentation and examples // for how to query COM properties. JIVariant objTextAsVariant = (JIVariant) ( wbemEvent.callMethodA( "GetObjectText_", new Object[] { new Integer( 1 ) } ) )[ 0 ]; String asText = objTextAsVariant.getObjectAsString().getString(); System.out.println( asText ); } } catch ( Exception e ) { e.printStackTrace(); } finally { if ( null != dcomSession ) { try { JISession.destroySession( dcomSession ); } catch ( Exception ex ) { ex.printStackTrace(); } } } } } 

~

Leggi questo articolo .

JNA 3.2.8 ha entrambi i metodi per leggere e scrivere dal registro eventi di Windows.

Puoi vedere un esempio di scrittura in log4jna .

Ecco un esempio di lettura:

 EventLogIterator iter = new EventLogIterator("Application"); while(iter.hasNext()) { EventLogRecord record = iter.next(); System.out.println(record.getRecordNumber() + ": Event ID: " + record.getEventId() + ", Event Type: " + record.getType() + ", Event Source: " + record.getSource()); } 

Se si desidera un vero accesso al registro eventi da una macchina remota, sarà necessario trovare una libreria che implementa la specifica del protocollo remoto di EventLog . Sfortunatamente, non ho ancora trovato alcuna libreria di questo tipo in Java. Tuttavia, molte delle basi per l’implementazione di questo protocollo sono già state poste dai progetti JCIFS e JARAPAC. Il protocollo stesso (se non sbaglio) viene eseguito in cima al protocollo DCE / RPC (implementato da JARAPAC) che a sua volta viene eseguito sopra il protocollo SMB (implementato da JCIFS).

Ho già utilizzato JCIFS e JARAPAC per implementare alcuni dei protocolli cugini di EventLog, come l’accesso al registro remoto. Potrei essere cieco, ma la documentazione sembrava un po ‘scarsa per quanto riguarda JARAPAC. Se sei interessato a metterlo in pratica, posso condividere con te ciò che ho imparato quando ho del tempo libero!

Dopo!

ci sono un milione (e uno) opzioni qui;)

potresti guardare sigar

http://cpansearch.perl.org/src/DOUGM/hyperic-sigar-1.6.3-src/docs/javadoc/org/hyperic/sigar/win32/EventLog.html

badate però al licensing ….

oppure potresti essere veloce e sporco e solo eseguire periodicamente (e catturare l’output) D:> cscript.exe c: \ WINDOWS \ system32 \ eventquery.vbs / v

quindi utilizzare i parametri di filtraggio degli eventi per perfezionare i risultati ecc. http://technet.microsoft.com/en-us/library/cc772995(WS.10).aspx