OpenTelemetry instrumentation guidance. Use AUTOMATICALLY when: - Adding new API endpoints - Creating new services/datasources - Implementing complex operations - Debugging production issues Ensures proper tracing and observability.
Guide proper OpenTelemetry instrumentation for observability.
HTTP Request (automatic)
└── GraphQL Operation
└── Resolver: Query.users
└── DataSource: getUsers
└── HTTP: GET /api/users
import { trace } from '@opentelemetry/api';
const tracer = trace.getTracer('my-service');
async function complexOperation(data: Data) {
return tracer.startActiveSpan('complexOperation', async (span) => {
try {
span.setAttribute('data.id', data.id);
const result = await doWork(data);
span.setStatus({ code: SpanStatusCode.OK });
return result;
} catch (error) {
span.setStatus({
code: SpanStatusCode.ERROR,
message: error.message
});
span.recordException(error);
throw error;
} finally {
span.end();
}
});
}
span.setAttribute('user.id', userId);
span.setAttribute('operation.type', 'fetch');
span.setAttribute('result.count', results.length);
span.addEvent('cache.miss', {
'cache.key': cacheKey,
});
The GraphQL server auto-instruments resolvers, but add context:
const resolvers = {
Query: {
users: async (_, args, context) => {
const span = trace.getActiveSpan();
span?.setAttribute('query.limit', args.limit);
// ... resolver logic
}
}
};
class UsersAPI extends RESTDataSource {
async getUser(id: string) {
return this.trace(
{ name: 'UsersAPI.getUser', attributes: { userId: id } },
() => this.get(`/users/${id}`)
);
}
}
| Category | Attributes |
|---|---|
| User | user.id, user.market |
| Operation | operation.name, operation.type |
| Request | http.method, http.url, http.status_code |
| GraphQL | graphql.operation.name, graphql.operation.type |
| Cache | cache.hit, cache.key |
| Error | error.type, error.message |
Traces are automatically sent to Sentry when configured:
import * as Sentry from '@sentry/node';
Sentry.init({
dsn: process.env.SENTRY_DSN,
tracesSampleRate: 0.1,
integrations: [
new Sentry.Integrations.OpenTelemetry(),
],
});