Plugin Types

BSB can be extended with four types of infrastructure plugins. Each plugin type has a specific base class and interface to implement.

Events Plugin

Route events between services. Implement RabbitMQ, Kafka, Redis Pub/Sub, or any message broker.

Extends BSBEvents

Logging Plugin

Send logs to external systems. Implement Graylog, Elasticsearch, Datadog, or custom log aggregators.

Extends BSBLogging

Config Plugin

Load configuration from external sources. Implement Consul, etcd, Vault, or custom config providers.

Extends BSBConfig

Metrics Plugin

Export metrics to monitoring systems. Implement Prometheus, OpenTelemetry, StatsD, or custom collectors.

Extends BSBMetrics

Creating an Events Plugin

An events plugin routes messages between services. Here's a skeleton for a RabbitMQ implementation:

import { BSBEvents, BSBEventsConstructor } from "@bettercorp/service-base";
import { Readable } from "node:stream";
import { DTrace } from "@bettercorp/service-base";

export class Plugin extends BSBEvents<null> {
  private connection: any; // Your RabbitMQ connection

  constructor(config: BSBEventsConstructor<null>) {
    super(config);
  }

  public async init(trace: DTrace) {
    // Connect to RabbitMQ
    this.connection = await connect(process.env.RABBITMQ_URL);
    this.log.info(trace, "Connected to RabbitMQ");
  }

  public async onBroadcast(
    trace: DTrace,
    pluginName: string,
    event: string,
    listener: (trace: DTrace, args: any[]) => Promise<void>
  ): Promise<void> {
    // Subscribe to a fanout exchange
  }

  public async emitBroadcast(
    trace: DTrace,
    pluginName: string,
    event: string,
    args: any[]
  ): Promise<void> {
    // Publish to a fanout exchange
  }

  public async onEvent(
    trace: DTrace,
    pluginName: string,
    event: string,
    listener: (trace: DTrace, args: any[]) => Promise<void>
  ): Promise<void> {
    // Subscribe to a queue
  }

  public async emitEvent(
    trace: DTrace,
    pluginName: string,
    event: string,
    args: any[]
  ): Promise<void> {
    // Publish to a queue
  }

  public async onReturnableEvent(
    trace: DTrace,
    pluginName: string,
    event: string,
    listener: (trace: DTrace, args: any[]) => Promise<any>
  ): Promise<void> {
    // Subscribe to RPC queue
  }

  public async emitEventAndReturn(
    trace: DTrace,
    pluginName: string,
    event: string,
    timeoutSeconds: number,
    args: any[]
  ): Promise<any> {
    // Publish to RPC queue and wait for response
  }

  // Stream methods...
  public async receiveStream(...) { }
  public async sendStream(...) { }

  public dispose() {
    this.connection?.close();
  }
}

Creating a Logging Plugin

A logging plugin receives log messages and sends them to an external system:

import { BSBLogging, BSBLoggingConstructor } from "@bettercorp/service-base";
import { DTrace, LogMeta } from "@bettercorp/service-base";

export class Plugin extends BSBLogging<null> {
  constructor(config: BSBLoggingConstructor<null>) {
    super(config);
  }

  public async debug<T extends string>(
    plugin: string,
    trace: DTrace,
    message: T,
    meta?: LogMeta<T>
  ): Promise<void> {
    await this.sendToGraylog("debug", plugin, trace, message, meta);
  }

  public async info<T extends string>(
    plugin: string,
    trace: DTrace,
    message: T,
    meta?: LogMeta<T>
  ): Promise<void> {
    await this.sendToGraylog("info", plugin, trace, message, meta);
  }

  public async warn<T extends string>(
    plugin: string,
    trace: DTrace,
    message: T,
    meta?: LogMeta<T>
  ): Promise<void> {
    await this.sendToGraylog("warn", plugin, trace, message, meta);
  }

  public async error<T extends string>(
    plugin: string,
    trace: DTrace,
    message: T,
    errorOrMeta?: Error | LogMeta<T>,
    meta?: LogMeta<T>
  ): Promise<void> {
    await this.sendToGraylog("error", plugin, trace, message, meta);
  }

  private async sendToGraylog(level: string, ...args: any[]) {
    // Send to Graylog GELF endpoint
  }
}

Plugin Discovery

BSB discovers plugins in this order:

  1. ./src/plugins/ - Local development plugins
  2. ./lib/plugins/ - Compiled plugins
  3. $BSB_PLUGIN_DIR/ - External plugin directory (for Docker)
  4. node_modules/ - npm-installed plugins

Name your plugin folder with the appropriate prefix: events-*, logging-*, config-*, or metrics-*.