Last updated Mar 5, 2020

Auditing your events

Bitbucket Data Center includes auditing functionality allowing events to be audited. Audited events are recorded in a log file and persisted in the database (which are then viewable via the audit UI). Plugins are also able to add audit events.

Bitbucket 7.0 onward

The following section explains how to use the @Auditable API to add audit events to the system. This API was added in Bitbucket 7.0 and should be used for all auditing going forwards. It is recommended to update any usages of the legacy @Audited to use @Auditable instead for better control over how your events are audited.

How to add your events to the audit feature

Adding audit events to the application involves annotating an object with @Auditable (typically a class extends ApplicationEvent), then publishing this object using the event framework.

The following arguments are required on the @Auditable annotation:

Event with annotation:

1
2
@Auditable(
        category = AuditCategory.REPOSITORIES,
        converter = MyConverter.class,
        coverageLevel = CoverageLevel.BASE)
class MyEvent extends ApplicationEvent {
    private final String data;
    private final Repository repository;
    
    public MyEvent(Object source, String data, Repository repository) {
        super(source);

        this.data = data;
        this.repository = repository;
    }

    public String getData() {
        return data;
    }

    public Repository getRepository() {
        return repository;
    }
}

Converter:

1
2
public class MyConverter implements AuditEventConverter<MyEvent> {
    @Nonnull
    @Override
    public AuditEvent convert(@Nonnull MyEvent event,
                              @Nonnull AuditEvent.Builder builder) {
          return builder
              //AuditUtils contains helper methods for adding affected objects for Bitbucket Data Center entities like projects and repositories
              //Other affected objects can be added by creating an AuditResource directly
              .affectedObjects(AuditUtils.auditResourcesForProjectAndRepository(event.getRepository()))
              //Extra attributes can be added via the extraAttributes builder method and creating an AuditAttribute
              .extraAttributes(new AuditAttribute("my-key", event.getData()))
              .build();
    }
}

Usage:

1
2
eventPublisher.publish(new MyEvent(this));

Additional information about using @Auditable:

  • Many of the audit event fields are set automatically by the system (e.g. author, timestamp, source, node)
  • The action field of the AuditEvent defaults to the event class but this can be overridden in the converter
  • If migrating an event that used to use the @Audited annotation, see the API changelog for how the old AuditEntry model and the new AuditEvent/AuditEntity models relate

Choosing a coverage level

CoverageLevel is an enum field which represents the level that the event should be logged at. A system administrator has the ability to configure all plugin events to a specific CoverageLevel (or OFF). For example, a system administrator could set the CoverageLevel for plugins events to BASE, which would mean all ADVANCED and FULL plugin events would not be not audited.

Choosing a category

The category specified in the @Auditable annotation is a free String field that is used in the auditing UI for searching and grouping events. Bitbucket Data Center categories are available via the AuditCategory class and it is recommended to use one of these categories where appropriate (e.g. AuditCategory.REPOSITORIES if your event if repository related). However it is also possible to specify your own category, which is useful if your plugin doesn't relate to any of the categories provided by Bitbucket.

Prior to Bitbucket Data Center 7.0

The following section explains how to use the legacy @Audited API to add audit events to the system. This API was deprecated in 7.0. It is recommended to use the new @Auditable API instead for better control over how your event is audited.

How to add your events to the audit feature

Adding audit events to the application involves annotating an object with @Audited (typically a class extends ApplicationEvent), then publishing this object using the event framework.

Event with annotation:

1
2
@Audited(converter=MyConverter.class, channels={Channels.REPOSITORY_UI}, priority = Priority.HIGH)
class MyEvent extends ApplicationEvent {
    private final Repository repository;

    public MyEvent(Object source, Repository repository) {
        super(source);
    }

    public Repository getRepository() {
        return repository;
    }
}

Converter:

1
2
public class MyConverter implements AuditEntryConverter<MyEvent> {
    @Nonnull
    @Override
    public AuditEntry convert(@Nonnull MyEvent event,
                              @Nonnull AuditEntryBuilder builder) {
          return builder
              .action(event.getClass())
              .timestamp(new Date())
              .details(getDetails(event))
              .user(event.getUser())
              .repository(event.getRepository())
              .build();
    }
}

Usage:

1
2
eventPublisher.publish(new MyEvent(this));

Additional information about using @Audited:

  • Adding a repository or project: If you are specifying that the event should be displayed in the project or repository UI you must tell the auditing system which project or repository by adding them in the builder. Note that from Bitbucket Data Center 7.0 onward, all events are persisted (and viewable in the UI).
  • Event details: the events added to the audit system by Bitbucket Data Center use a JSON format in their details strings for consistency although it is not required.
  • Data: all the required information must be available in the event for use in the converter.

Choosing a priority

The priority of your event should reflect the event's importance to users. HIGH priority events will be logged by default so they should be of interest to all Bitbucket administrators. Generally speaking events occurring due to normal development workflow are considered LOW or MEDIUM priority events. Events which alter the server's configuration or allow users greater privileges are considered HIGH priority.

Note that Priority was deprecated in Bitbucket 7.0, and the priority specified via an @Audited annotation will be ignored. Switch to use @Auditable and supply a CoverageLevel instead.

Add it to the UI?

Adding an event to the project or repository audit tab incurs a cost to the system (storing the data in the database). Events which are added to the UI should not be fired frequently. Events in the UI should be those which an administrator would want quick access to. Most events are intended for general auditing and so are just available to system administrators via the log file.

Note that from Bitbucket 7.0 onward, all audit events are persisted regardless of Channels (or lack thereof). Giving your event the best CoverageLevel (via @Auditable) will assist in making sure it is only shown in the UI where appropriate.

Common mistakes

  • Using the deprecated @Audited API. The system internally converts legacy AuditEntrys supplied by an AuditEntryConverter to the new AuditEvent/AuditEntity model via a best effort conversion, but this is not perfect. Audit events supplied in this way will have a default fallback CoverageLevel set for example. For full control over how your events are audited in Bitbucket 7.0 and onward, it is recommended to switch to the new @Auditable API (using an AuditEventConverter).
  • Publishing audited events too often. There is a system overhead for processing auditing events. While effort is made to process events as efficiently as possible (e.g. taking processing off the event thread, processing in batches, and other optimizations), excessive publishing of audited actions could slow the system down or cause audit events to be dropped.
  • Subclassing Bitbucket Data Center events. Although it is possible to subclass Bitbucket Data Center events it is discouraged as it may have unintended effects. The event system will pass a subclass to the internal auditing handlers which are expecting the parent class. Annotating a subclassed Bitbucket Data Center event for auditing is likely to result in the event being audited twice.

Rate this page: