Node.js
Logsβ
- logzio-nodejs
- winston-logzio
logzio-nodejs collects log messages in an array, which is sent asynchronously when it reaches its size limit or time limit (100 messages or 10 seconds), whichever comes first. It contains a simple retry mechanism which upon connection reset or client timeout, tries to send a waiting bulk (2 seconds default).
It's asynchronous, so it doesn't block other messages from being collected and sent. The interval increases by a factor of 2 between each retry until it reaches the maximum allowed attempts (3).
By default, any error is logged to the console. You can change this by using a callback function.
Configure logzio-nodejsβ
Add the dependency to your projectβ
Navigate to your project's folder in the command line, and run this command to install the dependency.
npm install logzio-nodejs
Configure logzio-nodejsβ
Use the samples in the code block below as a starting point, and replace the sample with a configuration that matches your needs.
For a complete list of options, see the configuration parameters below the code block.π
// Replace these parameters with your configuration
var logger = require('logzio-nodejs').createLogger({
token: '<<LOG-SHIPPING-TOKEN>>',
protocol: 'https',
host: '<<LISTENER-HOST>>',
port: '8071',
type: 'YourLogType'
});
Parametersβ
Parameter | Description | Required/Default |
---|---|---|
token | Your Logz.io log shipping token securely directs the data to your Logz.io account. Replace <<LOG-SHIPPING-TOKEN>> with the token of the account you want to ship to. | Required |
protocol | http or https . The value of this parameter affects the default of the port parameter. | http |
host | Use the listener URL specific to the region where your Logz.io account is hosted. Click to look up your listener URL. The required port depends whether HTTP or HTTPS is used: HTTP = 8070, HTTPS = 8071. Replace <<LISTENER-HOST>> with the host for your region. For example, listener.logz.io if your account is hosted on AWS US East, or listener-nl.logz.io if hosted on Azure West Europe. The required port depends whether HTTP or HTTPS is used: HTTP = 8070, HTTPS = 8071. | listener.logz.io |
port | Destination port. The default port depends on the protocol parameter: 8070 (for HTTP) or 8071 (for HTTPS) | 8070 / 8071 |
type | Declare your log type for parsing purposes. Logz.io applies default parsing pipelines to the following list of built-in log types. If you declare another type, contact support for assistance with custom parsing. Can't contain spaces. | nodejs |
sendIntervalMs | Time to wait between retry attempts, in milliseconds. | 2000 (2 seconds) |
bufferSize | Maximum number of messages the logger accumulates before sending them all as a bulk. | 100 |
numberOfRetries | Maximum number of retry attempts. | 3 |
debug | Set to true to print debug messsages to the console. | false |
callback | A callback function to call when the logger encounters an unrecoverable error. The function API is function(err) , where err is the Error object. | -- |
timeout | Read/write/connection timeout, in milliseconds. | -- |
extraFields | JSON format. Adds your custom fields to each log. Format: extraFields : { field_1: "val_1", field_2: "val_2" , ... } | -- |
setUserAgent | Set to false to send logs without the user-agent field in the request header. | true |
Code sampleβ
You can send log lines as a raw string or as an object. For more consistent and reliable parsing, we recommend sending logs as objects.
To send an object (recommended):
var obj = {
message: 'Some log message',
param1: 'val1',
param2: 'val2'
};
logger.log(obj);
To send raw text:
logger.log('This is a log message');
Include this line at the end of the run if you're using logzio-nodejs in a severless environment, such as AWS Lambda, Azure Functions, or Google Cloud Functions:
logger.sendAndClose();
Custom tagsβ
You can add custom tags to your logs using the following format: { tags : ['tag1']}
, for example:
var obj = {
message: 'Your log message',
tags : ['tag1']
};
logger.log(obj);
This winston plugin is a wrapper for the logzio-nodejs appender, which basically means it just wraps our nodejs logzio shipper. With winston-logzio, you can take advantage of the winston logger framework with your Node.js app.
Configure winston-logzioβ
Before you begin, you'll need: Winston 3 (If you're looking for Winston 2, checkout v1.0.8). If you need to run with Typescript, follow the procedure to set up winston with Typescript.
Add the dependency to your projectβ
Navigate to your project's folder in the command line, and run this command to install the dependency.
npm install winston-logzio --save
Configure winston-logzioβ
Here's a sample configuration that you can use as a starting point. Use the samples in the code block below or replace the sample with a configuration that matches your needs.
const winston = require('winston');
const LogzioWinstonTransport = require('winston-logzio');
const logzioWinstonTransport = new LogzioWinstonTransport({
level: 'info',
name: 'winston_logzio',
token: '<<LOG-SHIPPING-TOKEN>>',
host: '<<LISTENER-HOST>>',
});
const logger = winston.createLogger({
format: winston.format.simple(),
transports: [logzioWinstonTransport],
});
logger.log('warn', 'Just a test message');
If winston-logzio is used as part of a serverless service (AWS Lambda, Azure Functions, Google Cloud Functions, etc.), add await logger.info(βAPI Calledβ)
and logger.close()
at the end of the run, every time you are using the logger.
Replace the placeholders to match your specifics. (They are indicated by the double angle brackets << >>
):
Replace
<<LOG-SHIPPING-TOKEN>>
with the token of the account you want to ship to.Replace
<<LISTENER-HOST>>
with the host for your region. For example,listener.logz.io
if your account is hosted on AWS US East, orlistener-nl.logz.io
if hosted on Azure West Europe. The required port depends whether HTTP or HTTPS is used: HTTP = 8070, HTTPS = 8071.
Parametersβ
For a complete list of your options, see the configuration parameters below.π
Parameter | Description | Required/Default |
---|---|---|
LogzioWinstonTransport | This variable determines what will be passed to the logzio nodejs logger itself. If you want to configure the nodejs logger, add any parameters you want to send to winston when initializing the transport. | -- |
token | Your Logz.io log shipping token securely directs the data to your Logz.io account. Replace <<LOG-SHIPPING-TOKEN>> with the token of the account you want to ship to. | Required |
protocol | http or https . The value here affects the default of the port parameter. | http |
host | Use the listener URL specific to the region where your Logz.io account is hosted. Click to look up your listener URL. The required port depends whether HTTP or HTTPS is used: HTTP = 8070, HTTPS = 8071. Replace <<LISTENER-HOST>> with the host for your region. For example, listener.logz.io if your account is hosted on AWS US East, or listener-nl.logz.io if hosted on Azure West Europe. The required port depends whether HTTP or HTTPS is used: HTTP = 8070, HTTPS = 8071. | listener.logz.io |
port | Destination port. The default port depends on the protocol parameter: 8070 (for HTTP) or 8071 (for HTTPS) | 8070 / 8071 |
type | Declare your log type for parsing purposes. Logz.io applies default parsing pipelines to the following list of built-in log types. If you declare another type, contact support for assistance with custom parsing. Can't contain spaces. | nodejs |
sendIntervalMs | Time to wait between retry attempts, in milliseconds. | 2000 (2 seconds) |
bufferSize | Maximum number of messages the logger will accumulate before sending them all as a bulk. | 100 |
numberOfRetries | Maximum number of retry attempts. | 3 |
debug | To print debug messsages to the console, true . Otherwise, false . | false |
callback | A callback function to call when the logger encounters an unrecoverable error. The function API is function(err) , where err is the Error object. | -- |
timeout | Read/write/connection timeout, in milliseconds. | -- |
extraFields | JSON format. Adds your custom fields to each log. Format: extraFields : { field_1: "val_1", field_2: "val_2" , ... } | -- |
setUserAgent | Set to false to send logs without the user-agent field in the request header. If you want to send data from Firefox browser, set that option to false. | true |
Additional configuration optionsβ
If winston-logzio is used as part of a serverless service (AWS Lambda, Azure Functions, Google Cloud Functions, etc.), add this line at the end of the configuration code block.
logger.close()
The winston logger by default sends all logs to the console. You can easily disable this by adding this line to your code:
winston.remove(winston.transports.Console);
To send a log line:
winston.log('info', 'winston logger configured with logzio transport');
To log the last UncaughtException before Node exits:
var logzIOTransport = new (winstonLogzIO)(loggerOptions);
var logger = new(winston.Logger)({
transports: [
logzIOTransport
],
exceptionHandlers: [
logzIOTransport
],
exitOnError: true // set this to true
});
process.on('uncaughtException', function (err) {
logger.error("UncaughtException processing: %s", err);
logzIOTransport.flush( function(callback) {
process.exit(1);
});
});Another configuration option
var winston = require('winston');
var logzioWinstonTransport = require('winston-logzio');
// Replace these parameters with your configuration
var loggerOptions = {
token: '<<LOG-SHIPPING-TOKEN>>',
protocol: 'https',
host: '<<LISTENER-HOST>>',
port: '8071',
type: 'YourLogType'
};
winston.add(logzioWinstonTransport, loggerOptions);
Custom tagsβ
You can add custom tags to your logs using the following format: { tags : ['tag1']}
, for example:
var obj = {
message: 'Your log message',
tags : ['tag1']
};
logger.log(obj);
winston-logzio setup with Typescriptβ
This winston plugin is a wrapper for the logzio-nodejs appender that runs with Typescript, which basically means it just wraps our nodejs logzio shipper. With winston-logzio, you can take advantage of the winston logger framework with your Node.js app.
Configure winston-logzioβ
Before you begin, you'll need: Winston 3 (If you're looking for Winston 2, checkout v1.0.8)
Add the dependency to your projectβ
Navigate to your project's folder in the command line, and run this command to install the dependency.
npm install winston-logzio --save
Configure winston-logzio with Typescriptβ
If you don't have a tsconfig.json
file, you'll need to add it first. Start by running:
tsc --init
On your tsconfig.json
file, under the parameter compilerOptions
make sure you have the esModuleInterop
flag set to true
or add it:
"compilerOptions": {
...
"esModuleInterop": true
}
Here's a sample configuration that you can use as a starting point. Use the samples in the code block below or replace the sample with a configuration that matches your needs.
import winston from 'winston';
import LogzioWinstonTransport from 'winston-logzio';
const logzioWinstonTransport = new LogzioWinstonTransport({
level: 'info',
name: 'winston_logzio',
token: '<<LOG-SHIPPING-TOKEN>>',
host: '<<LISTENER-HOST>>',
});
const logger = winston.createLogger({
format: winston.format.simple(),
transports: [logzioWinstonTransport],
});
logger.log('warn', 'Just a test message');
If winston-logzio is used as part of a serverless service (AWS Lambda, Azure Functions, Google Cloud Functions, etc.), add this line at the end of the configuration code block, every time you are using the logger.
await logger.info(βAPI Calledβ)
logger.close()
Replace the placeholders to match your specifics. (They are indicated by the double angle brackets << >>
):
Replace
<<LOG-SHIPPING-TOKEN>>
with the token of the account you want to ship to.Replace
<<LISTENER-HOST>>
with the host for your region. For example,listener.logz.io
if your account is hosted on AWS US East, orlistener-nl.logz.io
if hosted on Azure West Europe. The required port depends whether HTTP or HTTPS is used: HTTP = 8070, HTTPS = 8071.
Troubleshootingβ
To fix errors related to esModuleInterop
flag make sure you run the relevant tsconfig
file.
These might help:
tsc <file-name>.ts --esModuleInterop
or
tsc --project tsconfig.json
Custom tagsβ
You can add custom tags to your logs using the following format: { tags : ['tag1']}
, for example:
var obj = {
message: 'Your log message',
tags : ['tag1']
};
logger.log(obj);
Metricsβ
Deploy this integration to send custom metrics from your Node.js application to Logz.io.
The provided example uses the OpenTelemetry JS SDK and is based on OpenTelemetry exporter collector proto.
Before you begin, you'll need:
Node 8 or higher
We advise to use this integration with the Logz.io Metrics backend. However, the integration is compatible with all backends that support metrics in prometheuesrmotewrite
format.
Configuring your Node.js application to send custom metrics to Logz.ioβ
Install the SDK packageβ
npm install logzio-nodejs-metrics-sdk@0.4.0
Initialize the exporter and meter providerβ
Add the following code to your application:
const MeterProvider = require('@opentelemetry/sdk-metrics-base');
const sdk = require('logzio-nodejs-metrics-sdk');
const collectorOptions = {
url: '<<LISTENER-HOST>>',
headers: {
"Authorization":"Bearer <<PROMETHEUS-METRICS-SHIPPING-TOKEN>>"
}
};
// Initialize the exporter
const metricExporter = new sdk.RemoteWriteExporter(collectorOptions);
// Initialize the meter provider
const meter = new MeterProvider.MeterProvider({
exporter: metricExporter,
interval: 15000, // Push interval in milliseconds
}).getMeter('example-exporter');
Replace the placeholders to match your specifics. (They are indicated by the double angle brackets << >>
):
- Replace
<<LISTENER-HOST>>
with the Logz.io Listener URL for your region, configured to use port 8052 for http traffic, or port 8053 for https traffic. For example,listener.logz.io
if your account is hosted on AWS US East, orlistener-nl.logz.io
if hosted on Azure West Europe. - Replace
<<PROMETHEUS-METRICS-SHIPPING-TOKEN>>
with a token for the Metrics account you want to ship to.
Here's how to look up your Metrics token.
Add required metrics to the codeβ
This integration allows you to use the following metrics:
Name | Behavior |
---|---|
Counter | Metric value can only go up or be reset to 0, calculated per counter.Add(context,value,labels) request. |
UpDownCounter | Metric value can arbitrarily increment or decrement, calculated per updowncounter.Add(context,value,labels) request. |
Histogram | Metric values captured by the histogram.Record(context,value,labels) function, calculated per request. |
For more information on each of these metrics, see the OpenTelemetry documentation.
To add a required metric to your code, copy and paste the required metric code to your application, placing it after the initialization code:
Counterβ
// Create your first counter metric
const requestCounter = meter.createCounter('Counter', {
description: 'Example of a Counter',
});
// Define some labels for your metrics
const labels = { environment: 'prod' };
// Record some value
requestCounter.add(1,labels);
// In logzio Metrics you will see the following metric:
// Counter_total{environment: 'prod'} 1.0
UpDownCounterβ
// Create UpDownCounter metric
const upDownCounter = meter.createUpDownCounter('UpDownCounter', {
description: 'Example of a UpDownCounter',
});
// Define some labels for your metrics
const labels = { environment: 'prod' };
// Record some values
upDownCounter.add(5,labels);
upDownCounter.add(-1,labels);
// In logzio you will see the following metric:
// UpDownCounter{environment: 'prod'} 4.0
Histogram:β
// Create ValueRecorder metric
const histogram = meter.createHistogram('test_histogram', {
description: 'Example of a histogram',
});
// Define some labels for your metrics
const labels = { environment: 'prod' };
// Record some values
histogram.record(30,labels);
histogram.record(20,labels);
// In logzio you will see the following metrics:
// test_histogram_sum{environment: 'prod'} 50.0
// test_histogram_count{environment: 'prod'} 2.0
// test_histogram_avg{environment: 'prod'} 25.0
Run your applicationβ
Run your application to start sending metrics to Logz.io.
Check Logz.io for your metricsβ
Give your metrics some time to get from your system to ours, and then open Metrics dashboard.
Tracesβ
Deploy this integration to enable automatic instrumentation of your Node.js application using OpenTelemetry.
Manual configurationβ
This integration includes:
- Installing the OpenTelemetry Node.js instrumentation packages on your application host
- Installing the OpenTelemetry collector with Logz.io exporter
- Running your Node.js application in conjunction with the OpenTelemetry instrumentation
On deployment, the Node.js instrumentation automatically captures spans from your application and forwards them to the collector, which exports the data to your Logz.io account.
Setup auto-instrumentation for your locally hosted Node.js application and send traces to Logz.ioβ
Before you begin, you'll need:
- A Node.js application without instrumentation
- An active account with Logz.io
- Port
4318
available on your host system - A name defined for your tracing service. You will need it to identify the traces in Logz.io.
This integration uses OpenTelemetry Collector Contrib, not the OpenTelemetry Collector Core.
Download instrumentation packagesβ
Run the following command from the application directory:
npm install --save @opentelemetry/api
npm install --save @opentelemetry/instrumentation
npm install --save @opentelemetry/sdk-trace-base
npm install --save @opentelemetry/exporter-trace-otlp-http
npm install --save @opentelemetry/resources
npm install --save @opentelemetry/semantic-conventions
npm install --save @opentelemetry/auto-instrumentations-node
npm install --save @opentelemetry/sdk-node
Create a tracer fileβ
In the directory of your application file, create a file named tracer.js
with the following configuration:
"use strict";
const {
BasicTracerProvider,
ConsoleSpanExporter,
SimpleSpanProcessor,
} = require("@opentelemetry/sdk-trace-base");
const { OTLPTraceExporter } = require("@opentelemetry/exporter-trace-otlp-http");
const { Resource } = require("@opentelemetry/resources");
const {
SemanticResourceAttributes,
} = require("@opentelemetry/semantic-conventions");
const opentelemetry = require("@opentelemetry/sdk-node");
const {
getNodeAutoInstrumentations,
} = require("@opentelemetry/auto-instrumentations-node");
const exporter = new OTLPTraceExporter({
url: "http://localhost:4318/v1/traces"
});
const provider = new BasicTracerProvider({
resource: new Resource({
[SemanticResourceAttributes.SERVICE_NAME]:
"YOUR-SERVICE-NAME",
}),
});
// export spans to console (useful for debugging)
provider.addSpanProcessor(new SimpleSpanProcessor(new ConsoleSpanExporter()));
// export spans to opentelemetry collector
provider.addSpanProcessor(new SimpleSpanProcessor(exporter));
provider.register();
const sdk = new opentelemetry.NodeSDK({
traceExporter: exporter,
instrumentations: [getNodeAutoInstrumentations()],
});
sdk
.start()
console.log("Tracing initialized");
process.on("SIGTERM", () => {
sdk
.shutdown()
.then(() => console.log("Tracing terminated"))
.catch((error) => console.log("Error terminating tracing", error))
.finally(() => process.exit(0));
});
Download and configure OpenTelemetry collectorβ
Create a dedicated directory on the host of your Node.js application and download the OpenTelemetry collector that is relevant to the operating system of your host.
After downloading the collector, create a configuration file config.yaml
with the following parameters:
receivers:
otlp:
protocols:
grpc:
endpoint: "0.0.0.0:4317"
http:
endpoint: "0.0.0.0:4318"
exporters:
logzio/traces:
account_token: "<<TRACING-SHIPPING-TOKEN>>"
region: "<<LOGZIO_ACCOUNT_REGION_CODE>>"
logging:
processors:
batch:
tail_sampling:
policies:
[
{
name: policy-errors,
type: status_code,
status_code: {status_codes: [ERROR]}
},
{
name: policy-slow,
type: latency,
latency: {threshold_ms: 1000}
},
{
name: policy-random-ok,
type: probabilistic,
probabilistic: {sampling_percentage: 10}
}
]
extensions:
pprof:
endpoint: :1777
zpages:
endpoint: :55679
health_check:
service:
extensions: [health_check, pprof, zpages]
pipelines:
traces:
receivers: [otlp]
processors: [tail_sampling, batch]
exporters: [logging, logzio/traces]
Replace <<TRACING-SHIPPING-TOKEN>>
with the token of the account you want to ship to.
Replace <LOGZIO_ACCOUNT_REGION_CODE>
with the applicable region code.
Start the collectorβ
Run the following command from the directory of your application file:
<path/to>/otelcontribcol_<VERSION-NAME> --config ./config.yaml
- Replace
<path/to>
with the path to the directory where you downloaded the collector. - Replace
<VERSION-NAME>
with the version name of the collector applicable to your system, e.g.otelcontribcol_darwin_amd64
.
Run the applicationβ
Run the application to generate traces:
node --require './tracer.js' <YOUR-APPLICATION-FILE-NAME>.js
Check Logz.io for your tracesβ
Give your traces some time to get from your system to ours, and then open Tracing.
Setup auto-instrumentation for your Node.js application using Docker and send traces to Logz.ioβ
This integration enables you to auto-instrument your Node.js application and run a containerized OpenTelemetry collector to send your traces to Logz.io. If your application also runs in a Docker container, make sure that both the application and collector containers are on the same network.
Before you begin, you'll need:
- A Node.js application without instrumentation
- An active account with Logz.io
- Port
4317
available on your host system - A name defined for your tracing service. You will need it to identify the traces in Logz.io.
Download instrumentation packagesβ
Run the following command from the application directory:
npm install --save @opentelemetry/api
npm install --save @opentelemetry/instrumentation
npm install --save @opentelemetry/sdk-trace-base
npm install --save @opentelemetry/exporter-trace-otlp-http
npm install --save @opentelemetry/resources
npm install --save @opentelemetry/semantic-conventions
npm install --save @opentelemetry/auto-instrumentations-node
npm install --save @opentelemetry/sdk-node
Create a tracer fileβ
In the directory of your application file, create a file named tracer.js
with the following configuration:
"use strict";
const {
BasicTracerProvider,
ConsoleSpanExporter,
SimpleSpanProcessor,
} = require("@opentelemetry/sdk-trace-base");
const { OTLPTraceExporter } = require("@opentelemetry/exporter-trace-otlp-http");
const { Resource } = require("@opentelemetry/resources");
const {
SemanticResourceAttributes,
} = require("@opentelemetry/semantic-conventions");
const opentelemetry = require("@opentelemetry/sdk-node");
const {
getNodeAutoInstrumentations,
} = require("@opentelemetry/auto-instrumentations-node");
const exporter = new OTLPTraceExporter({
url: "http://localhost:4318/v1/traces"
});
const provider = new BasicTracerProvider({
resource: new Resource({
[SemanticResourceAttributes.SERVICE_NAME]:
"YOUR-SERVICE-NAME",
}),
});
// export spans to console (useful for debugging)
provider.addSpanProcessor(new SimpleSpanProcessor(new ConsoleSpanExporter()));
// export spans to opentelemetry collector
provider.addSpanProcessor(new SimpleSpanProcessor(exporter));
provider.register();
const sdk = new opentelemetry.NodeSDK({
traceExporter: exporter,
instrumentations: [getNodeAutoInstrumentations()],
});
sdk
.start()
console.log("Tracing initialized");
process.on("SIGTERM", () => {
sdk
.shutdown()
.then(() => console.log("Tracing terminated"))
.catch((error) => console.log("Error terminating tracing", error))
.finally(() => process.exit(0));
});
Pull the Docker image for the OpenTelemetry collectorβ
docker pull otel/opentelemetry-collector-contrib:0.78.0
Create a configuration fileβ
Create a file config.yaml
with the following content:
receivers:
otlp:
protocols:
grpc:
endpoint: "0.0.0.0:4317"
http:
endpoint: "0.0.0.0:4318"
exporters:
logzio/traces:
account_token: "<<TRACING-SHIPPING-TOKEN>>"
region: "<<LOGZIO_ACCOUNT_REGION_CODE>>"
logging:
processors:
batch:
tail_sampling:
policies:
[
{
name: policy-errors,
type: status_code,
status_code: {status_codes: [ERROR]}
},
{
name: policy-slow,
type: latency,
latency: {threshold_ms: 1000}
},
{
name: policy-random-ok,
type: probabilistic,
probabilistic: {sampling_percentage: 10}
}
]
extensions:
pprof:
endpoint: :1777
zpages:
endpoint: :55679
health_check:
service:
extensions: [health_check, pprof, zpages]
pipelines:
traces:
receivers: [otlp]
processors: [tail_sampling, batch]
exporters: [logging, logzio/traces]
Replace <<TRACING-SHIPPING-TOKEN>>
with the token of the account you want to ship to.
Replace <LOGZIO_ACCOUNT_REGION_CODE>
with the applicable region code.
Tail Samplingβ
The tail_sampling
defines the decision to sample a trace after the completion of all the spans in a request. By default, this configuration collects all traces that have a span that was completed with an error, all traces that are slower than 1000 ms, and 10% of the rest of the traces.
You can add more policy configurations to the processor. For more on this, refer to OpenTelemetry Documentation.
The configurable parameters in the Logz.io default configuration are:
Parameter | Description | Default |
---|---|---|
threshold_ms | Threshold for the spand latency - all traces slower than the threshold value will be filtered in. | 1000 |
sampling_percentage | Sampling percentage for the probabilistic policy. | 10 |
If you already have an OpenTelemetry installation, add the following parameters to the configuration file of your existing OpenTelemetry collector:
- Under the
exporters
list
logzio/traces:
account_token: <<TRACING-SHIPPING-TOKEN>>
region: <<LOGZIO_ACCOUNT_REGION_CODE>>
- Under the
service
list:
extensions: [health_check, pprof, zpages]
pipelines:
traces:
receivers: [otlp]
processors: [tail_sampling, batch]
exporters: [logzio/traces]
Replace <<TRACING-SHIPPING-TOKEN>>
with the token of the account you want to ship to.
Replace <LOGZIO_ACCOUNT_REGION_CODE>
with the applicable region code.
An example configuration file looks as follows:
receivers:
otlp:
protocols:
grpc:
http:
exporters:
logzio/traces:
account_token: "<<TRACING-SHIPPING-TOKEN>>"
region: "<<LOGZIO_ACCOUNT_REGION_CODE>>"
processors:
batch:
tail_sampling:
policies:
[
{
name: policy-errors,
type: status_code,
status_code: {status_codes: [ERROR]}
},
{
name: policy-slow,
type: latency,
latency: {threshold_ms: 1000}
},
{
name: policy-random-ok,
type: probabilistic,
probabilistic: {sampling_percentage: 10}
}
]
extensions:
pprof:
endpoint: :1777
zpages:
endpoint: :55679
health_check:
service:
extensions: [health_check, pprof, zpages]
pipelines:
traces:
receivers: [otlp]
processors: [tail_sampling, batch]
exporters: [logzio/traces]
Replace <<TRACING-SHIPPING-TOKEN>>
with the token of the account you want to ship to.
Replace <LOGZIO_ACCOUNT_REGION_CODE>
with the applicable region code.
The tail_sampling
defines the decision to sample a trace after the completion of all the spans in a request. By default, this configuration collects all traces that have a span that was completed with an error, all traces that are slower than 1000 ms, and 10% of the rest of the traces.
You can add more policy configurations to the processor. For more on this, refer to OpenTelemetry Documentation.
The configurable parameters in the Logz.io default configuration are:
Parameter | Description | Default |
---|---|---|
threshold_ms | Threshold for the spand latency - all traces slower than the threshold value will be filtered in. | 1000 |
sampling_percentage | Sampling percentage for the probabilistic policy. | 10 |
Run the containerβ
Mount the config.yaml
as volume to the docker run
command and run it as follows.
Linuxβ
docker run \
--network host \
-v <PATH-TO>/config.yaml:/etc/otelcol-contrib/config.yaml \
otel/opentelemetry-collector-contrib:0.78.0
Replace <PATH-TO>
to the path to the config.yaml
file on your system.
Windowsβ
docker run \
-v <PATH-TO>/config.yaml:/etc/otelcol-contrib/config.yaml \
-p 55678-55680:55678-55680 \
-p 1777:1777 \
-p 9411:9411 \
-p 9943:9943 \
-p 6831:6831 \
-p 6832:6832 \
-p 14250:14250 \
-p 14268:14268 \
-p 4317:4317 \
-p 55681:55681 \
otel/opentelemetry-collector-contrib:0.78.0
Replace <<TRACING-SHIPPING-TOKEN>>
with the token of the account you want to ship to.
Replace <LOGZIO_ACCOUNT_REGION_CODE>
with the applicable region code.
Run the applicationβ
Normally, when you run the OTEL collector in a Docker container, your application will run in separate containers on the same host. In this case, you need to make sure that all your application containers share the same network as the OTEL collector container. One way to achieve this, is to run all containers, including the OTEL collector, with a Docker-compose configuration. Docker-compose automatically makes sure that all containers with the same configuration are sharing the same network.
Run the application to generate traces:
node --require './tracer.js' <YOUR-APPLICATION-FILE-NAME>.js
Check Logz.io for your tracesβ
Give your traces some time to get from your system to ours, and then open Tracing.
Configuratiion using Helmβ
You can use a Helm chart to ship Traces to Logz.io via the OpenTelemetry collector. The Helm tool is used to manage packages of pre-configured Kubernetes resources that use charts.
logzio-k8s-telemetry allows you to ship traces from your Kubernetes cluster to Logz.io with the OpenTelemetry collector.
This chart is a fork of the opentelemtry-collector Helm chart. The main repository for Logz.io helm charts are logzio-helm.
This integration uses OpenTelemetry Collector Contrib, not the OpenTelemetry Collector Core.
Standard configurationβ
1. Deploy the Helm chartβ
Add logzio-helm
repo as follows:
helm repo add logzio-helm https://logzio.github.io/logzio-helm
helm repo update
2. Run the Helm deployment codeβ
helm install \
--set secrets.LogzioRegion=<<LOGZIO_ACCOUNT_REGION_CODE>> \
--set secrets.TracesToken=<<TRACING-SHIPPING-TOKEN>> \
--set traces.enabled=true \
--set secrets.env_id=<<ENV_ID>> \
logzio-k8s-telemetry logzio-helm/logzio-k8s-telemetry
Replace <<TRACING-SHIPPING-TOKEN>>
with the token of the account you want to ship to.
Replace <LOGZIO_ACCOUNT_REGION_CODE>
with the applicable region code.
<<LOGZIO_ACCOUNT_REGION_CODE>>
- Your Logz.io account region code. Available regions.
3. Define the logzio-k8s-telemetry dns nameβ
In most cases, the service name will be logzio-k8s-telemetry.default.svc.cluster.local
, where default
is the namespace where you deployed the helm chart and svc.cluster.name
is your cluster domain name.
If you are not sure what your cluster domain name is, you can run the following command to look it up:
kubectl run -it --image=k8s.gcr.io/e2e-test-images/jessie-dnsutils:1.3 --restart=Never shell -- \
sh -c 'nslookup kubernetes.default | grep Name | sed "s/Name:\skubernetes.default//"'
It will deploy a small pod that extracts your cluster domain name from your Kubernetes environment. You can remove this pod after it has returned the cluster domain name.
Download instrumentation packagesβ
Run the following command from the application directory:
npm install --save @opentelemetry/api
npm install --save @opentelemetry/instrumentation
npm install --save @opentelemetry/sdk-trace-base
npm install --save @opentelemetry/exporter-trace-otlp-http
npm install --save @opentelemetry/resources
npm install --save @opentelemetry/semantic-conventions
npm install --save @opentelemetry/auto-instrumentations-node
npm install --save @opentelemetry/sdk-node
Create a tracer fileβ
In the directory of your application file, create a file named tracer.js
with the following configuration:
"use strict";
const {
BasicTracerProvider,
ConsoleSpanExporter,
SimpleSpanProcessor,
} = require("@opentelemetry/sdk-trace-base");
const { OTLPTraceExporter } = require("@opentelemetry/exporter-trace-otlp-http");
const { Resource } = require("@opentelemetry/resources");
const {
SemanticResourceAttributes,
} = require("@opentelemetry/semantic-conventions");
const opentelemetry = require("@opentelemetry/sdk-node");
const {
getNodeAutoInstrumentations,
} = require("@opentelemetry/auto-instrumentations-node");
const exporter = new OTLPTraceExporter({
url: "http://localhost:4318/v1/traces"
});
const provider = new BasicTracerProvider({
resource: new Resource({
[SemanticResourceAttributes.SERVICE_NAME]:
"YOUR-SERVICE-NAME",
}),
});
// export spans to console (useful for debugging)
provider.addSpanProcessor(new SimpleSpanProcessor(new ConsoleSpanExporter()));
// export spans to opentelemetry collector
provider.addSpanProcessor(new SimpleSpanProcessor(exporter));
provider.register();
const sdk = new opentelemetry.NodeSDK({
traceExporter: exporter,
instrumentations: [getNodeAutoInstrumentations()],
});
sdk
.start()
console.log("Tracing initialized");
process.on("SIGTERM", () => {
sdk
.shutdown()
.then(() => console.log("Tracing terminated"))
.catch((error) => console.log("Error terminating tracing", error))
.finally(() => process.exit(0));
});
4. Check Logz.io for your tracesβ
Give your traces some time to get from your system to ours, then open Logz.io.
Customizing Helm chart parametersβ
Configure customization optionsβ
You can use the following options to update the Helm chart parameters:
Specify parameters using the
--set key=value[,key=value]
argument tohelm install
.Edit the
values.yaml
.Overide default values with your own
my_values.yaml
and apply it in thehelm install
command.
If required, you can add the following optional parameters as environment variables:
Parameter | Description |
---|---|
secrets.SamplingLatency | Threshold for the spand latency - all traces slower than the threshold value will be filtered in. Default 500. |
secrets.SamplingProbability | Sampling percentage for the probabilistic policy. Default 10. |
Exampleβ
You can run the logzio-k8s-telemetry chart with your custom configuration file that takes precedence over the values.yaml
of the chart.
For example:
The collector will sample ALL traces where is some span with error with this example configuration.
baseCollectorConfig:
processors:
tail_sampling:
policies:
[
{
name: error-in-policy,
type: status_code,
status_code: {status_codes: [ERROR]}
},
{
name: slow-traces-policy,
type: latency,
latency: {threshold_ms: 400}
},
{
name: health-traces,
type: and,
and: {
and_sub_policy:
[
{
name: ping-operation,
type: string_attribute,
string_attribute: { key: http.url, values: [ /health ] }
},
{
name: main-service,
type: string_attribute,
string_attribute: { key: service.name, values: [ main-service ] }
},
{
name: probability-policy-1,
type: probabilistic,
probabilistic: {sampling_percentage: 1}
}
]
}
},
{
name: probability-policy,
type: probabilistic,
probabilistic: {sampling_percentage: 20}
}
]
helm install -f <PATH-TO>/my_values.yaml \
--set secrets.LogzioRegion=<<LOGZIO_ACCOUNT_REGION_CODE>> \
--set secrets.TracesToken=<<TRACING-SHIPPING-TOKEN>> \
--set traces.enabled=true \
--set secrets.env_id=<<ENV_ID>> \
logzio-k8s-telemetry logzio-helm/logzio-k8s-telemetry
Replace <PATH-TO>
with the path to your custom values.yaml
file.
Replace <<TRACING-SHIPPING-TOKEN>>
with the token of the account you want to ship to.
Replace <LOGZIO_ACCOUNT_REGION_CODE>
with the applicable region code.
Uninstalling the Chartβ
The uninstall command is used to remove all the Kubernetes components associated with the chart and to delete the release.
To uninstall the logzio-k8s-telemetry
deployment, use the following command:
helm uninstall logzio-k8s-telemetry
This section contains some guidelines for handling errors that you may encounter when trying to collect traces with OpenTelemetry.
Problem: No traces are sentβ
The code has been instrumented, but the traces are not being sent.
Possible cause - Collector not installedβ
The OpenTelemetry collector may not be installed on your system.
Suggested remedyβ
Check if you have an OpenTelemetry collector installed and configured to receive traces from your hosts.
Possible cause - Collector path not configuredβ
If the collector is installed, it may not have the correct endpoint configured for the receiver.
Suggested remedyβ
Check that the configuration file of the collector lists the following endpoints:
receivers:
otlp:
protocols:
grpc:
endpoint: "0.0.0.0:4317"
http:
endpoint: "0.0.0.0:4318"In the instrumentation code, make sure that the endpoint is specified correctly. Refer to our tracing documentation for more on this.
Possible cause - Traces not genereatedβ
If the collector is installed and the endpoints are properly configured, the instrumentation code may be incorrect.
Suggested remedyβ
- Check if the instrumentation can output traces to a console exporter.
- Use a web-hook to check if the traces are going to the output.
- Use the metrics endpoint of the collector (http://
<<COLLECTOR-HOST>>
:8888/metrics) to see the number of spans received per receiver and the number of spans sent to the Logz.io exporter.
- Replace
<<COLLECTOR-HOST>>
with the address of your collector host, e.g.localhost
, if the collector is hosted locally.
If the above steps do not work, refer to our tracing documentation and re-instrument the application.
Possible cause - Wrong exporter/protocol/endpointβ
If traces are generated but not send, the collector may be using incorrect exporter, protocol and/or endpoint.
The correct endpoints are:
receivers:
otlp:
protocols:
grpc:
endpoint: "<<COLLECTOR-URL>>:4317"
http:
endpoint: "<<COLLECTOR-URL>>:4318/v1/traces"
Suggested remedyβ
Activate
debug
logs in the configuration file of the collector as follows:service:
telemetry:
logs:
level: "debug"
Debug logs indicate the status code of the http/https post request.
If the post request is not successful, check if the collector is configured to use the correct exporter, protocol, and/or endpoint.
If the post request is successful, there will be an additional log with the status code 200. If the post request failed for some reason, there would be another log with the reason for the failure.
Possible cause - Collector failureβ
If the debug
logs are sent, but the traces are still not generated, the collector logs need to be investigated.
Suggested remedyβ
On Linux and MacOS, see the logs for the collector:
journalctl | grep otelcol
To only see errors:
journalctl | grep otelcol | grep Error
Otherwise, navigate to the following URL - http://localhost:8888/metrics
This is the endpoint to access the collector metrics in order to see different events that might happen within the collector - receiving spans, sending spans as well as other errors.
Possible cause - Exporter failureβ
Traces may not be generated if the exporter is not configured properly.
Suggested remedyβ
If you are unable to export traces to a destination, this may be caused by the following:
- There is a network configuration issue
- The exporter configuration is incorrect
- The destination is unavailable
To investigate this issue:
- Make sure that the
exporters
andservice: pipelines
are configured correctly. - Check the collector logs as well as
zpages
for potential issues. - Check your network configuration, such as firewall, DNS, or proxy.
For example, those metrics can provide information about the exporter:
# HELP otelcol_exporter_enqueue_failed_metric_points Number of metric points failed to be added to the sending queue.
# TYPE otelcol_exporter_enqueue_failed_metric_points counter
otelcol_exporter_enqueue_failed_metric_points{exporter="logging",service_instance_id="0582dab5-efb8-4061-94a7-60abdc9867e1",service_version="latest"} 0
Possible cause - Receiver failureβ
Traces may not be generated if the receiver is not configured properly.
Suggested remedyβ
If you are unable to receive data, this may be caused by the following:
- There is a network configuration issue
- The receiver configuration is incorrect
- The receiver is defined in the receivers section, but not enabled in any pipelines
- The client configuration is incorrect
Those metrics can provide about the receiver:
# HELP otelcol_receiver_accepted_spans Number of spans successfully pushed into the pipeline.
# TYPE otelcol_receiver_accepted_spans counter
otelcol_receiver_accepted_spans{receiver="otlp",service_instance_id="0582dab5-efb8-4061-94a7-60abdc9867e1",service_version="latest",transport="grpc"} 34
# HELP otelcol_receiver_refused_spans Number of spans that could not be pushed into the pipeline.
# TYPE otelcol_receiver_refused_spans counter
otelcol_receiver_refused_spans{receiver="otlp",service_instance_id="0582dab5-efb8-4061-94a7-60abdc9867e1",service_version="latest",transport="grpc"} 0