Resource Detectors in OpenTelemetry JavaScript
Resource detectors automatically detect and collect information about the environment in which your application is running. This information is attached to telemetry data (traces, metrics, and logs) to provide additional context for monitoring and debugging.
OpenTelemetry JavaScript provides several built-in resource detectors, and you can create custom detectors to gather application-specific information.
By default, OpenTelemetry JavaScript uses basic resource detection, but you can configure additional detectors:
const { NodeSDK } = require('@opentelemetry/sdk-node')
const { Resource } = require('@opentelemetry/resources')
const {
envDetector,
processDetector,
osDetector,
hostDetector,
} = require('@opentelemetry/resources')
const sdk = new NodeSDK({
resource: Resource.createDefault().merge(
new Resource({
'service.name': 'my-service',
'service.version': '1.0.0',
}),
),
resourceDetectors: [envDetector, processDetector, osDetector, hostDetector],
})
sdk.start()
Built-in detectors
Environment Variable Detector
Detects resource attributes from OTEL_RESOURCE_ATTRIBUTES and OTEL_SERVICE_NAME environment variables.
const { envDetector } = require('@opentelemetry/resources')
// Use in resource detectors array
resourceDetectors: [envDetector]
Environment variables:
export OTEL_SERVICE_NAME="user-api"
export OTEL_RESOURCE_ATTRIBUTES="service.version=1.2.0,deployment.environment=production"
Process Detector
Detects process-related attributes like PID, executable name, and command line arguments.
const { processDetector } = require('@opentelemetry/resources')
resourceDetectors: [processDetector]
Detected attributes:
process.pid- Process IDprocess.executable.name- Executable nameprocess.executable.path- Executable pathprocess.command_line- Command line argumentsprocess.command_args- Command arguments array
OS Detector
Detects operating system information.
const { osDetector } = require('@opentelemetry/resources')
resourceDetectors: [osDetector]
Detected attributes:
os.type- Operating system type (e.g., linux, darwin, win32)os.description- OS descriptionos.name- OS nameos.version- OS version
Host Detector
Detects host-related information.
const { hostDetector } = require('@opentelemetry/resources')
resourceDetectors: [hostDetector]
Detected attributes:
host.name- Hostnamehost.arch- Host architecture
Node.js integration
const { NodeSDK } = require('@opentelemetry/sdk-node')
const { Resource } = require('@opentelemetry/resources')
const {
envDetector,
processDetector,
osDetector,
hostDetector,
} = require('@opentelemetry/resources')
const sdk = new NodeSDK({
resource: Resource.createDefault().merge(
new Resource({
'service.name': 'user-api',
'service.version': '1.2.0',
'deployment.environment': 'production',
}),
),
resourceDetectors: [envDetector, processDetector, osDetector, hostDetector],
traceExporter: new OTLPTraceExporter({
url: 'https://api.uptrace.dev/v1/traces',
headers: { 'uptrace-dsn': process.env.UPTRACE_DSN },
}),
})
sdk.start()
Browser integration
For browser applications, resource detection is more limited due to security restrictions:
import { Resource } = from '@opentelemetry/resources'
import { WebTracerProvider } from '@opentelemetry/sdk-trace-web'
const resource = new Resource({
'service.name': 'web-app',
'service.version': '1.0.0',
'browser.name': navigator.userAgent,
'browser.language': navigator.language,
'browser.platform': navigator.platform,
})
const provider = new WebTracerProvider({
resource: resource,
})
Cloud detectors
AWS
For AWS environments, install the AWS detector package:
npm install @opentelemetry/resource-detector-aws
const { detectResources } = require('@opentelemetry/resources')
const {
awsEc2Detector,
awsEcsDetector,
awsEksDetector,
awsLambdaDetector,
} = require('@opentelemetry/resource-detector-aws')
// Detect resources first
const resource = await detectResources({
detectors: [
awsEc2Detector,
awsEcsDetector,
awsEksDetector,
awsLambdaDetector,
],
})
const sdk = new NodeSDK({
resource: resource,
traceExporter: new OTLPTraceExporter({
url: 'https://api.uptrace.dev/v1/traces',
headers: { 'uptrace-dsn': process.env.UPTRACE_DSN },
}),
})
await sdk.start()
Detected AWS attributes:
cloud.provider- AWScloud.platform- EC2, ECS, EKS, Lambdacloud.region- AWS regioncloud.availability_zone- Availability zonehost.id- Instance IDcontainer.id- Container ID (ECS/EKS)k8s.cluster.name- EKS cluster name
Google Cloud Platform
For GCP environments, install the GCP detector package:
npm install @opentelemetry/resource-detector-gcp
Note: This detector requires Node.js 18.19+ due to dependencies that use modern Node.js features.
const { detectResources } = require('@opentelemetry/resources')
const { gcpDetector } = require('@opentelemetry/resource-detector-gcp')
// Detect resources first
const resource = await detectResources({
detectors: [gcpDetector],
})
const sdk = new NodeSDK({
resource: resource,
traceExporter: new OTLPTraceExporter({
url: 'https://api.uptrace.dev/v1/traces',
headers: { 'uptrace-dsn': process.env.UPTRACE_DSN },
}),
})
await sdk.start()
Azure
Note: Azure resource detectors are not currently available as standalone packages in the OpenTelemetry JavaScript ecosystem. For Azure environments, use environment variables or custom detectors to add Azure-specific resource attributes:
const customAzureResource = new Resource({
'cloud.provider': 'azure',
'cloud.platform': process.env.AZURE_PLATFORM || 'azure_vm',
'cloud.region': process.env.AZURE_REGION,
'azure.vm.name': process.env.COMPUTERNAME,
'azure.resource_group': process.env.AZURE_RESOURCE_GROUP,
})
const sdk = new NodeSDK({
resource: Resource.createDefault().merge(customAzureResource),
resourceDetectors: [envDetector, processDetector],
})
sdk.start()
Container detectors
Docker
For Docker environments, install the container detector:
npm install @opentelemetry/resource-detector-container
const { detectResources } = require('@opentelemetry/resources')
const {
containerDetector,
} = require('@opentelemetry/resource-detector-container')
// Detect resources first
const resource = await detectResources({
detectors: [containerDetector],
})
const sdk = new NodeSDK({
resource: resource,
resourceDetectors: [envDetector, processDetector],
})
await sdk.start()
Detected container attributes:
container.name- Container namecontainer.id- Container IDcontainer.image.name- Image namecontainer.image.tag- Image tag
Custom resource detector
Create custom detectors by implementing the Detector interface:
const { Resource } = require('@opentelemetry/resources')
class CustomDetector {
async detect() {
return new Resource({
'deployment.datacenter': this.getDataCenter(),
'application.team': 'platform',
'application.owner': process.env.APP_OWNER || 'unknown',
'git.commit.sha': process.env.GIT_COMMIT || 'unknown',
})
}
getDataCenter() {
return process.env.DATACENTER || 'unknown'
}
}
// Usage with detectResources
async function initializeSDK() {
const customDetector = new CustomDetector()
const resource = await detectResources({
detectors: [envDetector, processDetector, customDetector],
})
const sdk = new NodeSDK({
resource: resource,
})
await sdk.start()
}
initializeSDK()
Advanced custom detector
Create more sophisticated custom detectors with async detection:
const { Resource } = require('@opentelemetry/resources')
const fs = require('fs').promises
class KubernetesDetector {
async detect() {
try {
// Check if running in Kubernetes
const namespaceFile =
'/var/run/secrets/kubernetes.io/serviceaccount/namespace'
const namespace = await fs.readFile(namespaceFile, 'utf8')
return new Resource({
'k8s.namespace.name': namespace.trim(),
'k8s.pod.name': process.env.HOSTNAME || 'unknown',
'k8s.cluster.name': process.env.CLUSTER_NAME || 'unknown',
})
} catch (error) {
// Not running in Kubernetes
return Resource.empty()
}
}
}
// Usage with async detection
async function initializeSDK() {
const k8sDetector = new KubernetesDetector()
const resource = await detectResources({
detectors: [envDetector, processDetector, k8sDetector],
})
const sdk = new NodeSDK({
resource: resource,
})
await sdk.start()
}
initializeSDK()
Manual attributes
Add custom attributes directly to resources:
const { Resource } = require('@opentelemetry/resources')
const customResource = new Resource({
'host.name': require('os').hostname(),
'process.pid': process.pid,
'deployment.environment': process.env.NODE_ENV || 'development',
'service.namespace': 'user-services',
'service.instance.id': `${require('os').hostname()}-${process.pid}`,
})
const sdk = new NodeSDK({
resource: Resource.createDefault().merge(customResource),
resourceDetectors: [envDetector, processDetector],
})
sdk.start()
Resource merging and precedence
Resources are merged in order, with later resources taking precedence:
const { Resource } = require('@opentelemetry/resources')
// Base resource (lowest precedence)
const baseResource = new Resource({
'service.name': 'default-service',
'service.version': '0.0.0',
'deployment.environment': 'development',
})
// Environment-specific overrides
const envResource = new Resource({
'service.name': process.env.SERVICE_NAME || 'default-service',
'service.version': process.env.SERVICE_VERSION || '0.0.0',
'deployment.environment': process.env.NODE_ENV || 'development',
})
// Final resource with precedence
const finalResource = baseResource.merge(envResource)
const sdk = new NodeSDK({
resource: finalResource,
resourceDetectors: [envDetector, processDetector],
})
sdk.start()
Querying resource data
Once your application is instrumented with resource detectors, you can use resource attributes in Uptrace for:
Identification and filtering
- Service topology: Visualize services using
service.nameandservice.namespace - Version tracking: Monitor deployments using
service.version - Environment separation: Filter by
deployment.environment
Infrastructure monitoring
- Host analysis: Group metrics by
host.nameandos.type - Container insights: Track containers using
container.nameandcontainer.id - Cloud resource tracking: Monitor cloud instances using
cloud.providerandcloud.region
Deployment and debugging
- Rollback identification: Track issues using
git.commit.sha - Team ownership: Route alerts using
application.team - Process debugging: Identify issues using
process.pidandprocess.command_line