Logging API
The Logging module provides observability for the Aletheia SDK through a pluggable logger interface and an event emitter for lifecycle events.
Classes
ConsoleLogger
Default logger that writes to the console with level filtering.
import { ConsoleLogger } from '@a2aletheia/sdk';
const logger = new ConsoleLogger("debug");
logger.info("Agent started", { port: 4000 });
// [aletheia:info] Agent started { port: 4000 }
Constructor
constructor(level?: AletheiaLogLevel)
Parameters:
level- Minimum log level to output (default:"info")
Levels are filtered by priority: debug < info < warn < error. Messages below the configured level are silently discarded.
// Only warn and error will be logged
const logger = new ConsoleLogger("warn");
logger.debug("This is ignored");
logger.info("This is ignored");
logger.warn("This appears"); // [aletheia:warn] This appears
logger.error("This appears"); // [aletheia:error] This appears
Methods
debug(message: string, context?: Record<string, unknown>): void
Logs a debug-level message.
logger.debug("Processing request", { requestId: "abc-123", step: "validation" });
info(message: string, context?: Record<string, unknown>): void
Logs an info-level message.
logger.info("Agent registered", { did: "did:web:agent.example.com" });
warn(message: string, context?: Record<string, unknown>): void
Logs a warning-level message.
logger.warn("Rate limit approaching", { remaining: 10, limit: 100 });
error(message: string, context?: Record<string, unknown>): void
Logs an error-level message.
logger.error("Connection failed", { endpoint: "https://api.example.com", error: "ECONNREFUSED" });
NoopLogger
Silent logger that discards all output. Use when you want to suppress SDK logging entirely.
import { NoopLogger } from '@a2aletheia/sdk';
const logger = new NoopLogger();
logger.info("This is silently ignored");
Methods
All methods are no-ops (no operation):
debug(message: string, context?: Record<string, unknown>): void
info(message: string, context?: Record<string, unknown>): void
warn(message: string, context?: Record<string, unknown>): void
error(message: string, context?: Record<string, unknown>): void
EventEmitter
Lightweight event emitter for Aletheia lifecycle events. Supports specific event types and a "*" wildcard that receives all events.
import { EventEmitter } from '@a2aletheia/sdk';
const emitter = new EventEmitter();
Constructor
constructor()
Methods
on(event: AletheiaEventType | "*", handler: AletheiaEventHandler): () => void
Subscribe to an event type. Returns an unsubscribe function.
Parameters:
event- The event type to subscribe to, or"*"for all eventshandler- Callback function invoked when the event is emitted
Returns: Unsubscribe function
// Listen to specific event
const unsub = emitter.on("agent.start", (event) => {
console.log("Agent started at", event.timestamp);
});
// Unsubscribe
unsub();
emit(event: AletheiaEventType, data?: Record<string, unknown>): void
Emit an event to all registered handlers (specific + wildcard).
Parameters:
event- The event type to emitdata- Optional data payload
emitter.emit("agent.start", { port: 4000, name: "MyAgent" });
Types
AletheiaLogger
Pluggable logger interface for the Aletheia SDK. Consumers can implement this interface with pino, winston, bunyan, OpenTelemetry, or any custom logger.
interface AletheiaLogger {
debug(message: string, context?: Record<string, unknown>): void;
info(message: string, context?: Record<string, unknown>): void;
warn(message: string, context?: Record<string, unknown>): void;
error(message: string, context?: Record<string, unknown>): void;
}
AletheiaLogLevel
Log level type used for filtering.
type AletheiaLogLevel = "debug" | "info" | "warn" | "error";
AletheiaEventType
Lifecycle event types emitted by the SDK.
type AletheiaEventType =
| "agent.start"
| "agent.stop"
| "message.received"
| "message.sent"
| "message.failed"
| "trust.verified"
| "trust.failed"
| "rating.submitted"
| "rating.received"
| "discovery.search"
| "discovery.connect"
| "liveness.check"
| "liveness.result";
AletheiaEvent
Event object passed to handlers.
interface AletheiaEvent {
type: AletheiaEventType;
timestamp: Date;
data?: Record<string, unknown>;
}
AletheiaEventHandler
Handler function signature for event subscriptions.
type AletheiaEventHandler = (event: AletheiaEvent) => void;
Event Types Reference
| Event | Description |
|---|---|
agent.start |
Agent server started listening |
agent.stop |
Agent server stopped |
message.received |
Incoming message received from another agent |
message.sent |
Message successfully sent to another agent |
message.failed |
Message delivery failed |
trust.verified |
Agent trust verification succeeded |
trust.failed |
Agent trust verification failed |
rating.submitted |
Rating submitted for an agent |
rating.received |
Rating received from another agent |
discovery.search |
Agent discovery search initiated |
discovery.connect |
Connection established with discovered agent |
liveness.check |
Liveness health check performed |
liveness.result |
Liveness check result received |
Examples
ConsoleLogger with Different Levels
import { ConsoleLogger } from '@a2aletheia/sdk';
// Production - only warnings and errors
const prodLogger = new ConsoleLogger("warn");
// Development - everything
const devLogger = new ConsoleLogger("debug");
// Testing - errors only
const testLogger = new ConsoleLogger("error");
NoopLogger Use Cases
import { AletheiaAgent, NoopLogger } from '@a2aletheia/sdk/agent';
// Silent agent for testing
const agent = new AletheiaAgent({
name: "TestAgent",
version: "1.0.0",
url: "https://test.example.com",
logger: new NoopLogger(),
// ...
});
// Or for production where you have external logging
const prodAgent = new AletheiaAgent({
name: "ProdAgent",
version: "1.0.0",
url: "https://prod.example.com",
logger: new NoopLogger(), // Using external APM/observability
// ...
});
EventEmitter with Wildcard Subscription
import { EventEmitter } from '@a2aletheia/sdk';
const emitter = new EventEmitter();
// Subscribe to all events for metrics
emitter.on("*", (event) => {
metrics.increment(`aletheia.events.${event.type}`);
metrics.histogram("aletheia.event_latency", Date.now() - event.timestamp.getTime());
});
// Subscribe to specific events
emitter.on("message.received", (event) => {
console.log("From:", event.data?.senderDid);
});
emitter.on("message.failed", (event) => {
alerting.trigger("message_failure", event.data);
});
// Chain subscriptions with cleanup
const cleanup = [
emitter.on("agent.start", handleStart),
emitter.on("agent.stop", handleStop),
emitter.on("trust.failed", handleTrustFailure),
];
// Unsubscribe all
cleanup.forEach(unsub => unsub());
BYOL - Bring Your Own Logger
Integrate with popular logging libraries:
Pino
import pino from 'pino';
import type { AletheiaLogger } from '@a2aletheia/sdk';
class PinoLogger implements AletheiaLogger {
constructor(private readonly logger: pino.Logger) {}
debug(message: string, context?: Record<string, unknown>): void {
this.logger.debug(context ?? {}, message);
}
info(message: string, context?: Record<string, unknown>): void {
this.logger.info(context ?? {}, message);
}
warn(message: string, context?: Record<string, unknown>): void {
this.logger.warn(context ?? {}, message);
}
error(message: string, context?: Record<string, unknown>): void {
this.logger.error(context ?? {}, message);
}
}
// Usage
const pinoInstance = pino({ level: 'debug' });
const logger = new PinoLogger(pinoInstance);
Winston
import winston from 'winston';
import type { AletheiaLogger } from '@a2aletheia/sdk';
class WinstonLogger implements AletheiaLogger {
constructor(private readonly logger: winston.Logger) {}
debug(message: string, context?: Record<string, unknown>): void {
this.logger.debug(message, context ?? {});
}
info(message: string, context?: Record<string, unknown>): void {
this.logger.info(message, context ?? {});
}
warn(message: string, context?: Record<string, unknown>): void {
this.logger.warn(message, context ?? {});
}
error(message: string, context?: Record<string, unknown>): void {
this.logger.error(message, context ?? {});
}
}
// Usage
const winstonInstance = winston.createLogger({
level: 'info',
format: winston.format.json(),
transports: [new winston.transports.Console()],
});
const logger = new WinstonLogger(winstonInstance);
OpenTelemetry
import { logs } from '@opentelemetry/api-logs';
import type { AletheiaLogger } from '@a2aletheia/sdk';
class OtelLogger implements AletheiaLogger {
private readonly logger = logs.getLogger('aletheia-sdk');
private emit(level: string, message: string, context?: Record<string, unknown>) {
const record = this.logger.createLogRecord();
record.setSeverityText(level);
record.setBody(message);
if (context) {
Object.entries(context).forEach(([k, v]) => {
record.setAttribute(k, v);
});
}
this.logger.emit(record);
}
debug(message: string, context?: Record<string, unknown>): void {
this.emit('DEBUG', message, context);
}
info(message: string, context?: Record<string, unknown>): void {
this.emit('INFO', message, context);
}
warn(message: string, context?: Record<string, unknown>): void {
this.emit('WARN', message, context);
}
error(message: string, context?: Record<string, unknown>): void {
this.emit('ERROR', message, context);
}
}
Integration with AletheiaAgent
import { AletheiaAgent, ConsoleLogger, NoopLogger } from '@a2aletheia/sdk/agent';
import { PinoLogger } from './my-loggers'; // Your custom logger
// Option 1: Use default ConsoleLogger with custom level
const agent1 = new AletheiaAgent({
name: "MyAgent",
version: "1.0.0",
url: "https://agent.example.com",
logLevel: "debug", // ConsoleLogger will use this level
});
// Option 2: Provide a custom logger instance
const agent2 = new AletheiaAgent({
name: "MyAgent",
version: "1.0.0",
url: "https://agent.example.com",
logger: new PinoLogger(pinoInstance),
});
// Option 3: Silence SDK logging entirely
const agent3 = new AletheiaAgent({
name: "MyAgent",
version: "1.0.0",
url: "https://agent.example.com",
logger: new NoopLogger(),
});
// Access the logger at runtime
agent.logger.info("Custom log from handler", { taskId: "123" });
// Subscribe to lifecycle events
agent.on("message.received", (event) => {
agent.logger.info("Processing message", event.data);
});
agent.on("message.failed", (event) => {
agent.logger.error("Message failed", event.data);
});
// Wildcard subscription for observability
agent.on("*", (event) => {
// Send to your APM/metrics system
apm.recordEvent(event.type, event.data);
});
Related APIs
- Agent Hosting - Full agent configuration options
- Types API - Full type definitions