@sphereon/ssi-sdk.event-logger
Version:
158 lines (136 loc) • 5.16 kB
text/typescript
import { AbstractEventLoggerStore } from '@sphereon/ssi-sdk.data-store-types'
import { Loggers, LoggingEventType, LogLevel, LogMethod } from '@sphereon/ssi-types'
import { ActivityLoggingEvent, AuditLoggingEvent } from '@sphereon/ssi-sdk.core'
import { IAgentPlugin } from '@veramo/core'
import { v4 as uuidv4 } from 'uuid'
import { schema } from '../index'
import {
EventLoggerOptions,
GetActivityEventsArgs,
GetAuditEventsArgs,
IEventLogger,
LogActivityEventArgs,
LogAuditEventArgs,
LogEventArgs,
LoggingEvent,
LogEventType,
RequiredContext,
} from '../types/IEventLogger'
/**
* {@inheritDoc IEventLogger}
*/
// Exposing the methods here for any REST implementation
export const eventLoggerAuditMethods: Array<string> = [
'loggerGetAuditEvents',
'loggerLogAuditEvent',
'loggerLogGeneralEvent',
'loggerLogActivityEvent',
'loggerGetActivityEvents',
]
export const eventLoggerMethods: Array<string> = [...eventLoggerAuditMethods]
export class EventLogger implements IAgentPlugin {
readonly schema = schema.IEventLogger
readonly eventTypes: Array<LoggingEventType> = []
private readonly store?: AbstractEventLoggerStore
readonly simpleLoggers: Loggers
readonly methods: IEventLogger = {
loggerGetAuditEvents: this.loggerGetAuditEvents.bind(this),
loggerLogAuditEvent: this.loggerLogAuditEvent.bind(this),
loggerLogGeneralEvent: this.loggerLogGeneralEvent.bind(this),
loggerLogActivityEvent: this.loggerLogActivityEvent.bind(this),
loggerGetActivityEvents: this.loggerGetActivityEvents.bind(this),
}
constructor(options: EventLoggerOptions) {
const { store, eventTypes } = options
const generalOpts = options.general ?? { debugPkg: true }
this.store = store
this.eventTypes = eventTypes
const methods: Array<LogMethod> = []
if (generalOpts.debugPkg) {
methods.push(LogMethod.DEBUG_PKG)
}
if (generalOpts.console) {
methods.push(LogMethod.CONSOLE)
}
if (generalOpts.events) {
methods.push(LogMethod.EVENT)
}
this.simpleLoggers = new Loggers({
methods,
eventName: generalOpts.eventName,
defaultLogLevel: generalOpts.defaultLogLevel,
})
}
public async onEvent(event: LoggingEvent, context: RequiredContext): Promise<void> {
switch (event.type) {
case LoggingEventType.AUDIT:
// Calling the context of the agent to make sure the REST client is called when configured
await context.agent.loggerLogAuditEvent({ event: event.data })
break
case LoggingEventType.GENERAL:
// Calling the context of the agent to make sure the REST client is called when configured
// TODO: We might also want to do this locally though, as these logs are not persisted typically
await context.agent.loggerLogGeneralEvent({ event: event.data })
break
case LoggingEventType.ACTIVITY:
// Calling the context of the agent to make sure the REST client is called when configured
await context.agent.loggerLogActivityEvent({ event: event.data })
break
default:
return Promise.reject(Error(`Event type ${event.type} not supported`))
}
}
private async loggerGetAuditEvents(args?: GetAuditEventsArgs): Promise<Array<AuditLoggingEvent>> {
const { filter } = args ?? {}
if (!this.store) {
return Promise.reject(Error('No store available in options'))
}
return this.store.getAuditEvents({ filter })
}
private async loggerGetActivityEvents(args?: GetActivityEventsArgs): Promise<Array<ActivityLoggingEvent>> {
const { filter } = args ?? {}
if (!this.store) {
return Promise.reject(Error('No store available in options'))
}
return this.store.getActivityEvents({ filter })
}
private async loggerLogGeneralEvent(args: LogEventArgs): Promise<LogEventType> {
const { event } = args
this.simpleLoggers.get(event.data.system).logl(event.data.level ?? LogLevel.INFO, event.data.data, event.data)
return args.event
}
private async loggerLogAuditEvent(args: LogAuditEventArgs): Promise<AuditLoggingEvent> {
const { event } = args
if (!this.store) {
return Promise.reject(Error('No store available in options'))
}
return this.store.storeAuditEvent({
event: {
...event,
system: event.system,
subSystemType: event.subSystemType,
initiatorType: event.initiatorType,
level: event.level ?? LogLevel.INFO,
correlationId: event.correlationId ?? uuidv4(),
timestamp: new Date(),
},
})
}
private async loggerLogActivityEvent(args: LogActivityEventArgs): Promise<ActivityLoggingEvent> {
const { event } = args
if (!this.store) {
return Promise.reject(Error('No store available in options'))
}
return this.store.storeActivityEvent({
event: {
...event,
system: event.system,
subSystemType: event.subSystemType,
initiatorType: event.initiatorType,
level: event.level ?? LogLevel.INFO,
correlationId: event.correlationId ?? uuidv4(),
timestamp: new Date(),
},
})
}
}