/** * cloudwatchObservability — Generic AWS CloudWatch Logs adapter. * * Ships every `AgentfootprintEvent` to a CloudWatch Logs stream. Use * when you want agent telemetry alongside the rest of your AWS * observability stack — CloudWatch Insights queries, alarms, * cross-service correlation. Same SDK as `agentcoreObservability` * but **without** the AgentCore-specific defaults (log-stream * convention, format opinions). Use this when: * * 1. You're shipping to CloudWatch but NOT running inside Bedrock * AgentCore (most common case). * 2. You want full control over log group / stream / format and * don't need AgentCore's hosted-agent telemetry conventions. * * Subpath: `agentfootprint/observe` * Peer dep: `@aws-sdk/client-cloudwatch-logs` (OPTIONAL — installed * only when this adapter is used; declared via * `peerDependenciesMeta.{name}.optional = true`). * * This module also exports the underlying base function used by * `agentcoreObservability` — keeps the per-event hot path in one * place so improvements (batching, retry, backpressure) flow to * every CloudWatch-shaped adapter automatically. * * @example * ```ts * import { cloudwatchObservability } from 'agentfootprint/observe'; * import { microtaskBatchDriver } from 'footprintjs/detach'; * * agent.enable.observability({ * strategy: cloudwatchObservability({ * region: 'us-east-1', * logGroupName: '/myapp/agent-prod', * logStreamName: `${process.env.HOSTNAME}/${Date.now()}`, * }), * detach: { driver: microtaskBatchDriver, mode: 'forget' }, * }); * ``` */ import type { AgentfootprintEvent } from '../../events/registry.js'; import type { ObservabilityStrategy } from '../../strategies/types.js'; export interface CloudwatchObservabilityOptions { /** AWS region. Falls back to AWS_REGION / AWS_DEFAULT_REGION env. */ readonly region?: string; /** CloudWatch Logs log group. **Required, and it must already exist.** * This adapter never creates it: a log group carries retention and * encryption decisions that belong to whoever provisions your account * (a group created with default retention never expires — an unbounded * bill), so provisioning it is control-plane work, same as the rest of * your infrastructure. Naming a group that does not exist means no * telemetry is delivered; the failure is reported through * {@link CloudwatchObservabilityOptions.onError}. */ readonly logGroupName: string; /** CloudWatch Logs log stream within the group. Conventionally * `/` so multi-instance deployments don't collide. * Created on first delivery if it does not exist — your role must allow * `logs:CreateLogStream`. The log GROUP is not created for you (see * {@link CloudwatchObservabilityOptions.logGroupName}). Defaults to * `agentfootprint`. */ readonly logStreamName?: string; /** Max events buffered before forced flush. Default 100. */ readonly maxBatchEvents?: number; /** Max payload bytes (UTF-8) buffered before forced flush. Default * 10240 (10 KB). CloudWatch hard caps at 1 MB / batch but we keep * the default low so latency stays bounded. */ readonly maxBatchBytes?: number; /** Forced-flush interval when traffic is sparse. Default 1000ms. * `0` disables time-based flush — only size triggers fire. */ readonly flushIntervalMs?: number; /** * Where delivery failures go (8.11.0). * * Shipping telemetry is network I/O and it fails: a missing log group, an * IAM denial, throttling, a batch CloudWatch rejects. Without this, those * failures reach the default sink — a rate-limited `console.error` — because * **telemetry that fails invisibly is indistinguishable from telemetry that * works**, and an exporter silently dropping every event is the worst * outcome this adapter can produce. * * Set this to route failures into your own logger instead. You receive * EVERY failure (the rate limiting applies only to the console fallback); * the batch that failed is dropped, never requeued, so an outage cannot * grow the buffer without bound. * * Equivalent to assigning the strategy's `_onError` property after * construction, but visible at the call site. */ readonly onError?: (error: Error, event?: AgentfootprintEvent) => void; /** Test injection — bypasses SDK lazy-require entirely. When set, * `region` / IAM are ignored. */ readonly _client?: CloudWatchLikeClient; /** @internal Test injection (9.4.0) — the AWS SDK module, so the real shim * (`send(new Command(...))`) runs against a fake SDK and the command names * it dispatches can be asserted. Ignored when `_client` is set. */ readonly _sdk?: CloudWatchSdkModule; } export interface CloudWatchLikeClient { putLogEvents(input: { logGroupName: string; logStreamName: string; logEvents: ReadonlyArray<{ timestamp: number; message: string; }>; }): Promise; /** * Create the log stream (8.11.0). OPTIONAL so an existing `_client` test * double that only implements `putLogEvents` still type-checks — the real * SDK-backed client always provides it. When a put fails because the stream * does not exist and this is absent, the adapter reports the failure rather * than creating anything. */ createLogStream?(input: { logGroupName: string; logStreamName: string; }): Promise; } /** * The slice of `@aws-sdk/client-cloudwatch-logs` this shim touches. * * Exported since 9.4.0 so `opts._sdk` can name it — which is what lets the * shared command-name pin (test/adapters/aws/) assert the OPERATIONS this * adapter dispatches without an AWS account or the peer dep installed. A * `_client` double proves the batching; only an `_sdk` double can prove the * adapter reaches for `PutLogEvents` and not something that does not exist. */ export interface CloudWatchSdkModule { readonly CloudWatchLogsClient?: new (config: { region?: string; }) => unknown; readonly PutLogEventsCommand?: new (input: unknown) => unknown; readonly CreateLogStreamCommand?: new (input: unknown) => unknown; } /** * Internal: shared CloudWatch Logs base used by every adapter that * ships to CWL. `cloudwatchObservability` is the public generic * factory; `agentcoreObservability` calls this with AgentCore-flavored * defaults. * * Exported for adapter authors only — consumers should call * `cloudwatchObservability` or `agentcoreObservability` directly. * * @internal */ export declare function _buildCloudWatchObservability(opts: CloudwatchObservabilityOptions, strategyName: string): ObservabilityStrategy; /** * Generic CloudWatch Logs observability adapter. See * `CloudwatchObservabilityOptions` for the per-option contract. * * For AgentCore-specific conventions, use `agentcoreObservability` * which thin-wraps this with AgentCore-flavored defaults. */ export declare function cloudwatchObservability(opts: CloudwatchObservabilityOptions): ObservabilityStrategy; //# sourceMappingURL=cloudwatch.d.ts.map