Giter Club home page Giter Club logo

gchq.event-logging's Introduction

Event Logging

Event Logging is a Java API for logging audit events conforming to the Event Logging XML Schema. The API uses a generated Java JAXB model of the Event Logging XML Schema. Event Logging can be incorporated into your Java application to provide a means of recording and outputting audit events or user actions for compliance, security or monitoring.

As this library is essentially a Java representation of the Event Logging XML Schema it helps to refer to the schema to better understand the Java model. The schema documentation provides a lot of detail about how to model events using the schema which will be helpful when using this library.

The Javadoc for the latest release of the library is available here.

This library requires Java 8 as a minimum. The only dependencies it brings with it are javax.xml.bind:jaxb-api and org.slf4j:slf4j-api.

By default the created events are serialised to XML and passed to a SLF4J logger which would typically be linked to a rolling file appender.

What to Log

The aim of this API is to capture the following information about an action/event.

  • Who - Who performed the action, i.e the user ID or some other identifer to link the event to a user and details of the user's device.
  • Where - Where did the event happen, i.e on what system, device, network address.
  • What - The detail of what they did, e.g. copy a file named X from A to B.
  • When - The time the event happend.
  • Why - The purpose and/or justification for their action, e.g. where compliance rules dictate that certain actions have prior approval. The requirement to capture the why is dependant on the rules in place for the system using this library.

Using the Event Logging API

Gradle/Maven dependencies

The Event Logging API is available as a Maven/Gradle dependency on Bintray. You will need to add our Bintray repository to your build tool. To include it in your Gradle build add the following:

repositories {
  //...
  maven { url "https://dl.bintray.com/stroom/event-logging" }
}

dependencies {
  compile 'event-logging:event-logging:v5.0-beta.9_schema-v4.0-beta.1'
}

NOTE:
Version 3.x.x+ of event-logging is compatible with Java 8+

The second version number in the version string is the version of the event-logging-schema XML Schema that the library uses.

Example Application

A standalone example application can be found in ./example-logged-application that shows how you can include logging in your application. See here for details.

Calling the API

The API has two main parts, the class model that represents the schema and the classes involved with serialising and logging the events.

Event Class Model

The class model is autogenerated from the XML schema and includes fluent builder classes and methods to make constructing an event easier. The top level class for constructing an event is event.logging.Event.

final Event event = Event.builder()
        //...
        .build();

Logging Service

The interface for logging audit events is EventLoggingService.java. A default implementation of this interface is included in the form of DefaultEventLoggingService.java. This simple implementation serialises the Event passed to it to an XML String and passes that to an implementation of LogReceiver.

By default this library will use the LoggerLogReceiver implementation to receive and handle the XML events. This implementation will write the XML to an SLF4J logger called event-logger. You then need to add configuration to your logging framework, i.e. Log4J/Logback/etc. to handle the event-logger logs, e.g. writing them to rolled log files. See here for an example Logback configuration.

Sending your rolled event logs to Stroom would then be done using something like send_to_stroom.sh or stroom-log-sender.

If you don't wish to use the LoggerLogReceiver to handle the logs, you can make your own implementation of LogReceiver. In order to use your own implementaion you need to set the system property event.logging.logreceiver with the fully qualified class name of your implementation. LogReceiverFactory will then issue new instances of your implementation instead of LoggerLogReceiver.

Examples

Examples of how to construct various types of events and log them can be found in the test class base/src/test/java/event/logging/EventLoggingServiceIT.java.

These examples assume you have created your own implementation of EventLoggingService that overrides the createEvent(...) methods. Using your own implemtation that extends DefaultEventLoggingService is the preferred approach to dealing with common values in your events. See CustomEventLoggingService for an example.

The following is a very simple example of logging an Authentication type event using the default logging service supplied with the API. This example does not use any common event values so

// Define your own implementation of EventLoggingService that provides common event values
public static class CustomEventLoggingService extends DefaultEventLoggingService {

    @Override
    public Event createEvent(final String typeId,
                             final String description,
                             final Purpose purpose,
                             final EventAction eventAction) {
        return Event.builder()
            .withEventTime(EventTime.builder()
                    .withTimeCreated(new Date())
                    .build())
            .withEventSource(EventSource.builder()
                    .withSystem(SystemDetail.builder()
                            .withName("My System Name")
                            .withEnvironment("Test")
                            .withVersion(getBuildVersion())
                            .build())
                    .withGenerator("CustomEventLoggingService")
                    .withClient(getClientDevice())
                    .withDevice(getThisDevice())
                    .withUser(User.builder()
                            .withId(getLoggedInUserId())
                            .build())
                    .build())
            .withEventDetail(EventDetail.builder()
                    .withTypeId(typeId)
                    .withDescription(description)
                    .withPurpose(purpose != null ? purpose : getSessionPurpose())
                    .withEventAction(eventAction)
                    .build())
            .build();
    }

}

// Create the logging service
final EventLoggingService eventLoggingService = new CustomEventLoggingService();

// Log some work that produces a result. This will make use of createEvent for common event values.
final UserAccount userAccount = eventLoggingService.loggedResult(
    "LOGON",
    "User " + userId + " logged on",
    AuthenticateEventAction.builder()
        .withAction(AuthenticateAction.LOGON)
        .withUser(User.builder()
                .withId(userId)
                .build())
        .build()
    () -> {
        // Perform authentication and logon

        // An exception here will cause an unsuccessful logon event to be logged
        // then the original exception will be re-thrown.

        return account;
    });

The various forms of the loggedXXX methods provide the simplest means of logging an event and handle failure cases for you, setting Outcome/Success to false if an exception is thrown. Some forms of loggedXXX allow the loggedWork lambda to return a LoggedOutcome object to indicate success/failure rather than using exceptions. There are also forms of these methods that allow you to change the logged EventAction based on the work being performed, e.g. if you need to add in the details of the results of a search. For examples of the various forms see App.java

For instances where you want to handle failure conditions manually you can use this approach:

eventLoggingService.log(
        "LogoffNowBanner",
        "User shown logoff now banner",
        ViewEventAction.builder()
                .addBanner(Banner.builder()
                        .withMessage("The system is about to be shutdown for maintenance, log off now!")
                        .build())
                .build());

When building the Event model you can use the fully fluent style (using the end() methods on the Builder classes) to build the event. While more compact, this is heavily reliant on careful indentation to ensure readability.

// Create the event object
final Event event = Event.builder()
        .withEventTime()
                .withTimeCreated(new Date())
                .end()
        .withEventSource()
                .withSystem()
                        .withName("Test System")
                        .withEnvironment("Test")
                        .end()
                .withGenerator("JUnit")
                .withDevice()
                        .withIPAddress("123.123.123.123")
                        .end()
                .withUser()
                        .withId("someuser")
                        .end()
                .end()
        .withEventDetail()
                .withTypeId("LOGON")
                .withDescription("A user logon")
                .withAuthenticate()
                        .withAction(AuthenticateAction.LOGON)
                        .withUser()
                                .withId("someuser")
                                .end()
                        .end()
                .end()
        .build();

event-logging is used by Stroom. You can see how it is used in Stroom here: StroomEventLoggingServiceImpl

Upgrading from v3/4 to v5

v5 of this library introduces a number of breaking changes that will require you to alter your existing event creation code if migrating to v5. We appreciate that introducing breaking changes causes a lot of pain and we don't do it lightly. Unfortunately there were a number of fundamental issues with the previous versions of the library that made it difficult to work with.

Fluent Builders

event-logging v5 has introduced fluent style builder classes and methods for each class in the Event model. These make creating events or sub-trees within events much easier and neater. There is however no requirement to change existing code to use the builders.

Moved Classes

For clarity all classes have been made top-level. Previously a lot of the classes were declared as static inner classes. Where this has happened, e.g. event.logging.Event.EventDetail => event.logging.EventDetail, it should just be case of fixing the import or removing the extra parent class from the qualifier.

Renamed Classes

The following classes have been renamed:

  • Event.EventDetail.Alert => AlertEventAction
  • Event.EventDetail.Approval => ApprovalEventAction
  • Event.EventDetail.Authenticate => AuthenticateEventAction
  • Event.EventDetail.Authorise => AuthoriseEventAction
  • Event.EventDetail.Authorise => AuthoriseEventAction
  • CopyMove => CopyEventAction & MoveEventAction
  • Export => ExportEventAction
  • Import => ImportEventAction
  • Install => InstallEventAction & InstallEventAction
  • Event.EventDetail.Network => NetworkEventAction
  • NetworkSrcDst => NetworkLocation
  • NetworkSrcDstTrasnportProtocol => NetworkProtocol
  • NetworkSrcDstTrasnportProtocol => NetworkProtocol
  • Object => OtherObject
  • Event.EventDetail.Print => PrintEventAction
  • Event.EventDetail.Process => ProcessEventAction
  • SendReceive => SendEventAction & ReceiveEventAction
  • Search => SearchEventAction
  • Unknown => UnknownEventAction
  • Event.EventDetail.Update => UpdateEventAction

Type changes

Some properties have had their classes changed for clarity:

  • ObjectOutcome Event.EventDetail.create => CreateEventAction EventDetail.create
  • ObjectOutcome Event.EventDetail.delete => DeleteEventAction EventDetail.delete
  • ObjectOutcome Event.EventDetail.search => SearchEventAction EventDetail.search
  • CopyMove Event.EventDetail.copy => CopyEventAction EventDetail.copy
  • CopyMove Event.EventDetail.move => MoveEventAction EventDetail.move
  • Install Event.EventDetail.uninstall => UninstallEventAction EventDetail.uninstall
  • ObjectOutcome Event.EventDetail.view => ViewEventAction EventDetail.view

Removed Classes

A number of deprecated classes and properties have been removed:

  • Event.EventDetail.antiMalware
  • AntiMalware
  • BaseAdvancedQueryItemComplexType - replaced with marker interface AdvancedQueryItem
  • SearchResult - use SearchResults instead.
  • Event.EventDetail.classification - use Event.classification instead.
  • From

New Interfaces

A number of new marker interfaces have been added to make the API clearer. For example all the possible event actions (e.g. send, create, delete, etc.) under EventDetail now implement the marker interface EventAction.

Developing this library

The documention for developers contributing to this library see here.

gchq.event-logging's People

Contributors

at055612 avatar jc064522 avatar stroomdev66 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.