Instrument
OpenTelemetry
Send existing OTLP traces, logs, and metrics to Anectico without replacing your instrumentation.
Anectico accepts OpenTelemetry Protocol data. Keep your current instrumentation and change the exporter destination and authentication header.
Endpoint and authentication
Use the Anectico ingestion host:
OTLP HTTP base: https://api.anectico.com
Header: X-Anectico-API-Key=an_...
Signal paths follow the OTLP HTTP convention:
/v1/traces
/v1/logs
/v1/metrics
Example environment configuration:
export OTEL_EXPORTER_OTLP_ENDPOINT="https://api.anectico.com"
export OTEL_EXPORTER_OTLP_HEADERS="X-Anectico-API-Key=an_..."
export OTEL_SERVICE_NAME="orders-api"
export OTEL_RESOURCE_ATTRIBUTES="deployment.environment=production"
Use an API key containing only ingest:write for collectors and application exporters.
Add Anectico features to an existing Python SDK
If your Python application already owns OpenTelemetry resources, sampling, providers, processors, exporters, instrumentation, and lifecycle, do not start a second telemetry pipeline. Keep those application providers, point their OTLP exporters or Collector at Anectico, and add Anectico’s identity-only processors before registering the providers:
import os
from opentelemetry import _logs as otel_logs
from opentelemetry import metrics, trace
import anectico
# These are the providers and export processors from your existing OTel setup.
tracer_provider.add_span_processor(anectico.BaggageIdentitySpanProcessor())
tracer_provider.add_span_processor(existing_span_export_processor)
logger_provider.add_log_record_processor(
anectico.BaggageIdentityLogRecordProcessor()
)
logger_provider.add_log_record_processor(existing_log_export_processor)
trace.set_tracer_provider(tracer_provider)
metrics.set_meter_provider(meter_provider)
otel_logs.set_logger_provider(logger_provider)
client = anectico.AnecticoClient(
api_key=os.environ["ANECTICO_API_KEY"],
service_name="marketplace-api",
open_telemetry_mode="existing",
)
client.start()
ANECTICO_OTEL_MODE=existing is equivalent. Register the identity processors before
application work emits spans or logs, and register the application providers
before starting Anectico. The processors only stamp anectico.distinct_id; they do not
export, register globals, or flush/shut down anything. Do not add person
identity to metric labels.
Existing mode creates no providers, exporters, export processors, metric
readers, propagator, requests/httpx instrumentation, or standard-library
logging bridge. Anectico’s manual spans, captured errors, AI/tool/agent helpers,
metrics, and log_event() use the registered global APIs. Without a real
application Logger Provider, log_event() is a safe no-op. Ordinary Python
logging continues through the application’s existing logging integration only.
The application owns sampling and export decisions. Anectico’s managed resource,
sampler, endpoint, batching, exporter, propagation, and logging-bridge settings
do not change the existing pipeline; Anectico signal enable flags still gate helper
emission. client.flush() returns False, and client.stop() returns
attempted=False, success=None, because neither call may flush or shut down
application providers. After the final helper call, stop Anectico and use the
application’s existing provider lifecycle hook to flush and shut down.
To roll back the Anectico feature layer, remove the client startup and the two identity processors. The original application-owned OTel pipeline stays in place. Restore its prior exporter/Collector destination and authentication separately if the rollback must also stop OTLP delivery to Anectico.
Add Anectico features to an existing Node SDK
If your application already starts NodeSDK or registers its own OpenTelemetry providers, keep that
code as the single owner of providers, processors, instrumentation, exporters, flush, and shutdown.
Start it first, point its OTLP exporters at Anectico, and initialize Anectico in existing-provider mode:
import { context, trace } from '@opentelemetry/api';
import { NodeSDK } from '@opentelemetry/sdk-node';
import {
BaggageLogRecordProcessor,
BaggageSpanProcessor,
contextWithDistinctId,
initNode,
} from '@anectico/sdk/node';
const otel = new NodeSDK({
// Keep your existing resource, instrumentations, and Anectico OTLP exporters.
// Add these identity-only processors before the application SDK starts.
spanProcessors: [
new BaggageSpanProcessor(),
// ...your existing export processors
],
logRecordProcessors: [
new BaggageLogRecordProcessor(),
// ...your existing export processors
],
});
otel.start();
const anectico = await initNode({
apiKey: process.env.ANECTICO_API_KEY,
serviceName: 'orders-api',
openTelemetryMode: 'existing',
});
const requestContext = contextWithDistinctId(context.active(), 'customer_8842');
await context.with(requestContext, async () => {
await trace.getTracer('orders-api').startActiveSpan('orders.create', async span => {
// Existing application work.
span.end();
});
});
openTelemetryMode: 'existing' (or ANECTICO_OTEL_MODE=existing) does not create providers, exporters,
propagators, or auto-instrumentations and never shuts down application-owned providers. Anectico’s
manual spans, errors, metrics, and logs use the globals your application registered. A signal needs
an existing provider to export: for example, logEvent() requires your application to have
registered an OpenTelemetry Logger Provider.
Add BaggageSpanProcessor and BaggageLogRecordProcessor to the application-owned providers before
they start when request-scoped contextWithDistinctId() or W3C baggage should become the
anectico.distinct_id attribute stored on spans and logs. These processors add identity attributes
only; they do not export, register globals, or own provider lifecycle. Metrics should remain
service-scoped and must not carry customer identity labels.
Keep lifecycle ownership in the application. On graceful or fatal shutdown, finish active work and
flush or shut down NodeSDK before calling anectico.stop() to finish Anectico identity requests and remove
its process handlers. anectico.flush() cannot flush providers it does not own. Do not combine the
default managed mode with an already-started OpenTelemetry SDK, and do not use the Anectico preload in
existing-provider mode. Removing the Anectico initialization later leaves the original OTLP-only
pipeline unchanged.
Attach customer identity to request evidence
OTLP data without customer identity still appears in service, trace, log, and metric views. To add traces and logs to a customer timeline, attach the stable ID as:
anectico.distinct_id=user_8842
For distributed requests, propagate the same value through trusted W3C baggage. Do not accept a customer identity directly from an unauthenticated public request. Do not copy customer identity onto metric labels: identifiers create high-cardinality series, and metrics are normally service-scoped evidence rather than one-customer timeline entries.
Resource fields that matter
Set these consistently:
| Field | Purpose |
|---|---|
service.name |
Groups telemetry by application or service |
service.version |
Connects failures to a release |
deployment.environment |
Separates production, staging, and development |
anectico.distinct_id |
Connects request evidence to a customer; do not use it as a metric label |
Verify
Send one span, one log, and one recognizable metric, then check Traces, Logs, and Metrics
in the same project and environment. Allow for the metric export interval and shut down the Meter
Provider cleanly in a short-lived test. If you supplied anectico.distinct_id on the request evidence,
also search Customers for that value.