• 1. Add the following dependencies to your build.gradle.kts (always keep this library up to date).

implementation("ph.safibank.common:utils:8.+")  // always try up-to-date version)

Please also ensure these dependencies are added:

implementation("io.micronaut.kafka:micronaut-kafka")
implementation("io.confluent:kafka-avro-serializer:7.1.1")
  • 2. Configure Kafka cluster properties in your application.yml.

kafka:
  schema.registry.url: ${SCHEMA_REGISTRY_URL}
  bootstrap:
    servers: ${KAFKA_URL}
  • 3. Declare a Kafka producer.

import io.micronaut.configuration.kafka.annotation.KafkaClient
import ph.safibank.kafka.backoffice.BackofficeCreateAuditLogCommandV1Producer

@KafkaClient("audit-log-producer")
abstract class AuditLogProducer : BackofficeCreateAuditLogCommandV1Producer()

You should always use the most recent version of audit log command avro schema, the schemas for audit log can be found in backoffice schemas.

  • 4. Publish a message to the topic when a relevant activity occurs in your code.

Use the provided buildAuditLogCommandAvro helper to build the event.

See also the Audit log data model and Audit log message examples

Example:

val eventAvro = buildAuditLogCommandAvro(
    sourceSystemName = SystemName.CUSTOMER_BACKEND, // this is resolved automatically
    action = EventActionTypeEnum.ATTRIBUTE_CHANGED,
    target = AuditLogCommandTarget(
      targetId = customerId.toString(),
      targetType = EventTargetTypeV4Enum.CUSTOMER,
      attributes = mapOf(
        AuditAttributeKeyEnum.CUSTOMER_ID to customerId.toString()
        // other is available
      )
    ),
    detail = mapOf(
      // use strings or string constants from AuditLogConstants
      AuditLogConstants.DETAIL_KEY_CUSTOMER_PREF_LANG to language.name
      AuditLogConstants.DETAIL_KEY_CUSTOMER_PREF_TONE to toneOfVoice.name
    )
)
auditLogProducer.send(
    idempotencyKey = idempotencyKey,
    messageKey = customerId,
    message = eventeventAvro
)
  • The Kafka messageKey should be the ID of the entity related to the log

    • Most of the time this should be the same as targetId

Important: Make sure to emit the event after all DB changes have been done so that it will not be limited in case of rollback.

Also do catch the errors from send - if there is an error sending the message the whole activity should rollback and fail.

AuditLogCommandSource

The source: AuditLogCommandSource is currently filled from the tracing headers, it will work if

  • the log is caused by customer via mobile app

  • the log is caused by backoffice user via BOFE

In other cases (i.e. system does this) you need to provide the AuditLogCommandSource yourself.

Note: Right now when a maker-checker is approved it gets applied by the system (triggered by the temporal workflow), so the ID/name of the BO user who made the pending change is not propagated into the log of that change baing applied. Instead the name of the system (like “Accounts backend”) is used.

This is not a critical issue but there may be some way how to propagate the tracing info through the temporal as well.

Adding more enum values

If more actions or source/target types must be added, please update in the common library (may also need to upgrade common-utils library’s version in backoffice-manager & audit-log-manager):

For updating or deleting a type, the version maybe need to be upgraded to avoid any breaking changes for other services.