Skip to content

Commit

Permalink
feat: support for custom log levels (#146)
Browse files Browse the repository at this point in the history
* feat: support for custom log levels

* refactor(opentelemetry-mapper): rename SEVERITY_NUMBER_MAP

* docs: expanded description of severityNumberMap option
  • Loading branch information
10xLaCroixDrinker committed Mar 7, 2024
1 parent 1ba1766 commit d3e0c82
Show file tree
Hide file tree
Showing 6 changed files with 65 additions and 20 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ When using the transport, the following options can be used to configure the tra
* `loggerName`: name to be used by the OpenTelemetry logger
* `serviceVersion`: version to be used by the OpenTelemetry logger
* `messageKey`: The key of the log message to be used as the OpenTelemetry log entry Body. Optional, value `msg` used by default (like in Pino itself). Optional
* `severityNumberMap`: Object mapping Pino log level numbers to OpenTelemetry log severity numbers. This is an override for adding custom log levels and changing default log levels. Undefined default Pino log levels will still be mapped to their default OpenTelemetry log severity. Optional
* `resourceAttributes`: Object containing [resource attributes](https://opentelemetry.io/docs/instrumentation/js/resources/). Optional
* `logRecordProcessorOptions`: a single object or an array of objects specifying the LogProcessor and LogExporter types and constructor params. Optional

Expand Down
22 changes: 11 additions & 11 deletions lib/opentelemetry-mapper.js
Original file line number Diff line number Diff line change
@@ -1,23 +1,22 @@
'use strict'

const { SeverityNumber } = require('@opentelemetry/api-logs') // TODO: optional import

/**
* If the source format has only a single severity that matches the meaning of the range
* then it is recommended to assign that severity the smallest value of the range.
* https://github.com/open-telemetry/opentelemetry-specification/blob/fc8289b8879f3a37e1eba5b4e445c94e74b20359/specification/logs/data-model.md#mapping-of-severitynumber
*/
const SEVERITY_NUMBER_MAP = {
10: SeverityNumber.TRACE,
20: SeverityNumber.DEBUG,
30: SeverityNumber.INFO,
40: SeverityNumber.WARN,
50: SeverityNumber.ERROR,
60: SeverityNumber.FATAL
const DEFAULT_SEVERITY_NUMBER_MAP = {
10: 1, // TRACE
20: 5, // DEBUG
30: 9, // INFO
40: 13, // WARN
50: 17, // ERROR
60: 21 // FATAL
}

// https://github.com/open-telemetry/opentelemetry-specification/blob/fc8289b8879f3a37e1eba5b4e445c94e74b20359/specification/logs/data-model.md#displaying-severity
const SEVERITY_NAME_MAP = {
0: 'UNSPECIFIED',
1: 'TRACE',
2: 'TRACE2',
3: 'TRACE3',
Expand Down Expand Up @@ -61,12 +60,13 @@ const SEVERITY_NAME_MAP = {
*
* @typedef {Object} MapperOptions
* @property {string} messageKey
* @property {Object.<number, number>} [severityNumberMap]
*
* @param {Bindings} sourceObject
* @param {MapperOptions} mapperOptions
* @returns {import('@opentelemetry/api-logs').LogRecord}
*/
function toOpenTelemetry (sourceObject, { messageKey }) {
function toOpenTelemetry (sourceObject, { messageKey, severityNumberMap = {} }) {
const {
time,
level,
Expand All @@ -77,7 +77,7 @@ function toOpenTelemetry (sourceObject, { messageKey }) {
} = sourceObject

const severityNumber =
SEVERITY_NUMBER_MAP[sourceObject.level] ?? SeverityNumber.UNSPECIFIED
severityNumberMap[sourceObject.level] ?? DEFAULT_SEVERITY_NUMBER_MAP[sourceObject.level] ?? 0
const severityText = SEVERITY_NAME_MAP[severityNumber] ?? 'UNSPECIFIED'

/* eslint-disable camelcase */
Expand Down
8 changes: 5 additions & 3 deletions lib/pino-opentelemetry-transport.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,18 @@ const DEFAULT_MESSAGE_KEY = 'msg'
*
* @typedef {Object} PinoOptions
* @property {string} [messageKey="msg"]
* @property {Object.<number, number>} [severityNumberMap]
*
* @typedef {PinoOptions & import('otlp-logger').Options} Options
*
* @param { Options } opts
*/
module.exports = async function (opts) {
const logger = getOtlpLogger(opts)
module.exports = async function ({ messageKey = DEFAULT_MESSAGE_KEY, severityNumberMap, ...loggerOpts }) {
const logger = getOtlpLogger(loggerOpts)

const mapperOptions = {
messageKey: opts.messageKey || DEFAULT_MESSAGE_KEY
messageKey,
severityNumberMap
}

return build(
Expand Down
1 change: 0 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
"repository": "github:Vunovati/pino-opentelemetry-transport",
"license": "MIT",
"dependencies": {
"@opentelemetry/api-logs": "^0.48.0",
"otlp-logger": "^1.1.0",
"pino-abstract-transport": "^1.1.0"
},
Expand Down
33 changes: 31 additions & 2 deletions test/lib/opentelemetry-mapper.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -104,21 +104,50 @@ test('toOpenTelemetry maps all log levels correctly', async ({ match }) => {
...testLogEntryBase,
level: 60
},
{ messageKey: 'msg' }
{
messageKey: 'msg',
severityNumberMap: {
35: 10
}
}
),
{
severityNumber: 21,
severityText: 'FATAL'
}
)

match(
toOpenTelemetry(
{
...testLogEntryBase,
level: 35
},
{
messageKey: 'msg',
severityNumberMap: {
35: 10
}
}
),
{
severityNumber: 10,
severityText: 'INFO2'
}
)

match(
toOpenTelemetry(
{
...testLogEntryBase,
level: 42
},
{ messageKey: 'msg' }
{
messageKey: 'msg',
severityNumberMap: {
35: 10
}
}
),
{
severityNumber: 0,
Expand Down
20 changes: 17 additions & 3 deletions test/lib/pino-opentelemetry-transport.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,6 @@ test('translate Pino log format to Open Telemetry data format for each log level
})

const transport = pino.transport({
level: 'trace',
target: '../..',
options: {
loggerName: 'test-logger-name',
Expand All @@ -69,12 +68,19 @@ test('translate Pino log format to Open Telemetry data format for each log level
exporterOptions: {
protocol: 'grpc'
}
},
severityNumberMap: {
35: 10
}
}
})

const logger = pino(transport, {})
logger.level = 'trace'
const logger = pino({
level: 'trace',
customLevels: {
custom: 35
}
}, transport)

const testTraceId = '12345678901234567890123456789012'
const testSpanId = '1234567890123456'
Expand All @@ -93,6 +99,7 @@ test('translate Pino log format to Open Telemetry data format for each log level
logger.trace(extra, 'test trace')
logger.debug('test debug')
logger.info('test info')
logger.custom('test custom')
logger.warn('test warn')
logger.error('test error')
logger.fatal('test fatal')
Expand Down Expand Up @@ -143,6 +150,13 @@ test('translate Pino log format to Open Telemetry data format for each log level
traceId: '',
spanId: ''
},
{
severityNumber: 10,
severityText: 'INFO2',
body: { stringValue: 'test custom' },
traceId: '',
spanId: ''
},
{
severityNumber: 13,
severityText: 'WARN',
Expand Down

0 comments on commit d3e0c82

Please sign in to comment.