2008-11-21 21 views
13

Gibt es eine Möglichkeit, auf das Windows-Ereignisprotokoll von einer Java-Klasse zuzugreifen. Hat jemand dafür irgendwelche APIs geschrieben, und gäbe es irgendeine Möglichkeit, von einem entfernten Rechner auf die Daten zuzugreifen?Wie greife ich auf Windows-Ereignisanzeige-Protokolldaten von Java zu

Das Szenario ist:

Ich betreibe einen Prozess auf einem entfernten Rechner, von einer Steuerung Java-Prozess. Dieser Remote-Prozess protokolliert Daten zum Ereignisprotokoll, die im Controlling-Prozess angezeigt werden sollen.

Vielen Dank im Voraus.

Antwort

9

Auf der Java-Seite benötigen Sie eine Bibliothek, mit der Sie native Anrufe tätigen können. Sun bietet JNI, aber es klingt wie eine Art von Schmerz. Sehen Sie sich auch:

Auf der Windows-Seite, die Funktion, die Sie nachdem es OpenEventLog. Dies sollte Ihnen ermöglichen, auf ein Remote-Ereignisprotokoll zuzugreifen. Siehe auch Querying for Event Information.

Wenn das nicht richtig klingen, fand ich auch diese direkt die Protokolldateien für das Parsen (keinen Ansatz, den ich empfehlen würde, aber trotzdem interessant):

1

Wenn Sie einen echten Ereignisprotokoll-Zugriff von einem Remote-Computer wünschen, müssen Sie eine Bibliothek finden, die die EventLog Remoting Protocol Specification implementiert. Leider habe ich noch keine solche Bibliothek in Java gefunden. Ein Großteil der Grundlage für die Umsetzung dieses Protokolls wurde jedoch bereits von den JCIFS- und JARAPAC-Projekten gelegt. Das Protokoll selbst (wenn ich mich nicht irre) läuft auf dem DCE/RPC-Protokoll (das von JARAPAC implementiert wird), das selbst auf dem SMB-Protokoll läuft (implementiert von JCIFS).

Ich habe bereits JCIFS und JARAPAC verwendet, um einige der Cousin-Protokolle von EventLog zu implementieren, z. B. Remote-Registry-Zugriff. Ich bin vielleicht blind, aber die Dokumentation scheint in Bezug auf JARAPAC etwas knapp zu sein. Wenn Sie daran interessiert sind, dies zu implementieren, kann ich mit Ihnen teilen, was ich gelernt habe, wenn ich etwas Freizeit habe!

Später!

17

http://www.j-interop.org/ ist eine Open-Source-Java-Bibliothek, die die DCOM-Protokoll-Spezifikation implementiert, ohne dass nativen Code zu verwenden. (d. h. Sie können damit auf DCOM-Objekte auf einem Remote-Windows-Host aus Java-Code zugreifen, der auf einem Nicht-Windows-Client ausgeführt wird).

Microsoft stellt eine Fülle von Systeminformationen über Windows Management Instrumentation (WMI) zur Verfügung. WMI ist remote über DCOM zugänglich, und umfangreiche Dokumentation zu diesem Thema befindet sich auf der Microsoft-Website. Zufällig können Sie über diese fernzugängliche Schnittstelle auf die Windows Event Logs zugreifen.

Mithilfe von j-interop können Sie eine Instanz des WMI-Objekts WbemScripting.SWbemLocator remote erstellen und dann eine Verbindung zu Windows Management Instrumentation-Diensten (WMI) auf dem Windows-Remote-Host herstellen. Von dort können Sie eine query senden, die Sie informiert, wenn ein neuer Ereignisprotokolleintrag geschrieben wird.

Beachten Sie, dass DCOM ordnungsgemäß auf dem Windows-Remote-Host aktiviert und konfiguriert werden muss und dass entsprechende Ausnahmen in Firewalls eingerichtet wurden. Details dazu können online durchsucht werden und werden auch von der oben genannten j-interop Seite referenziert.

Das folgende Beispiel stellt eine Verbindung zu einem Remote-Host unter Verwendung der NT-Domäne, des Hostnamens, eines Benutzernamens und eines Kennworts her und befindet sich in einer Schleife und löscht alle Ereignisprotokolleinträge, wenn sie von Windows protokolliert werden. Dem Benutzer müssen die entsprechenden Remote-DCOM-Zugriffsberechtigungen erteilt worden sein, er muss jedoch kein Administrator sein.

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 informed 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(); 
       } 
      } 
     } 
    } 

} 

~

1

gibt es eine Million (und ein) Optionen hier;)

Sie bei sigar

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

Geist der Lizenzierung obwohl aussehen könnte ....

oder Sie könnten schnell und schmutzig und nur periodi sein Ausführen nisch (und erfassen den Ausgang) D:> cscript.exe C: \ WINDOWS \ system32 \ eventquery.vbs/v

dann verwenden Ereignis params Filterung die Ergebnisse zu verbessern ... etc http://technet.microsoft.com/en-us/library/cc772995(WS.10).aspx

6

Lesen Sie this article.

JNA 3.2.8 verfügt über beide Methoden zum Lesen und Schreiben aus dem Windows-Ereignisprotokoll.

Sie können ein Beispiel des Schreibens in log4jna sehen.

Hier ist ein Beispiel von Lese:

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()); 
} 
Verwandte Themen