diff --git a/.eslintrc.js b/.eslintrc.js index 90e10f1..a3379f8 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -2,4 +2,7 @@ module.exports = { extends: "@krakenjs/eslint-config-grumbler/eslintrc-browser", + globals: { + $Shape: true, + }, }; diff --git a/README.md b/README.md index 380a8e7..c924b68 100644 --- a/README.md +++ b/README.md @@ -56,6 +56,20 @@ logger.metricCounter({ }) ``` +#### Using a namespace prefix + +``` +const logger = new Logger({...options, metricNamespacePrefix: "company.team.app"}) + +logger.metricCounter({ + namespace: "product.feature", + event: "button_click", +}) + +// creates metric with namespace of +// company.team.app.product.feature +``` + ### `$logger.metricGauge(, );` Queues a gauge metric, helper wrapping `logger.metric` @@ -71,6 +85,21 @@ logger.metricGauge({ }) ``` +#### Using a namespace prefix + +``` +const logger = new Logger({...options, metricNamespacePrefix: "company.team.app"}) + +logger.metricGauge({ + namespace: "product.feature", + event: "request_latency", + value: 100 +}) + +// creates metric with namespace of +// company.team.app.product.feature +``` + ### Deprecated - `$logger.metric(, );` Queues a metric. We suggest using the `metricCount` or `metricGauge` interface for better type safety and clearer intention in your code. diff --git a/src/logger.js b/src/logger.js index ad35cc2..3a406db 100644 --- a/src/logger.js +++ b/src/logger.js @@ -25,9 +25,10 @@ import type { MetricPayloadGauge, } from "./types"; -type LoggerOptions = {| +export type LoggerOptions = {| url?: string, prefix?: string, + metricNamespacePrefix?: string, logLevel?: $Values, transport?: Transport, flushInterval?: number, @@ -80,6 +81,7 @@ export type LoggerType = {| export function Logger({ url, prefix, + metricNamespacePrefix, logLevel = DEFAULT_LOG_LEVEL, transport = getHTTPTransport(), flushInterval = FLUSH_INTERVAL, @@ -283,6 +285,10 @@ export function Logger({ return logger; // eslint-disable-line no-use-before-define } + if (metricNamespacePrefix) { + metricPayload.metricNamespace = `${metricNamespacePrefix}.${metricPayload.metricNamespace}`; + } + if (metricDimensionBuilders.length > 0 && !metricPayload.dimensions) { metricPayload.dimensions = {}; } diff --git a/src/logger.test.js b/src/logger.test.js index ddfd20b..e6b67de 100644 --- a/src/logger.test.js +++ b/src/logger.test.js @@ -3,7 +3,7 @@ import { beforeEach, describe, expect, test, vi } from "vitest"; -import { Logger } from "."; +import { Logger, type LoggerOptions } from "."; const XMLHttpRequestMock = vi.fn(() => ({ open: vi.fn(), @@ -16,9 +16,13 @@ vi.stubGlobal("XMLHttpRequest", XMLHttpRequestMock); let logger; let logBuf; -const initLogger = ({ url = "/test/api/log" } = {}) => +const initLogger = ({ + url = "/test/api/log", + metricNamespacePrefix, +}: $Shape = {}) => Logger({ url, + metricNamespacePrefix, }); const getLoggerBuffer = (testLogger) => testLogger.__buffer__; @@ -266,7 +270,7 @@ describe("beaver logger provides flushing methods that send events to the server }); describe("metricCounter", () => { - test("should add metrics of counter type", () => { + test("adds metrics of counter type", () => { const testLogger = initLogger(); testLogger.metricCounter({ @@ -306,10 +310,27 @@ describe("metricCounter", () => { }, }); }); + + test("uses metric namespace prefix", () => { + const testLogger = initLogger({ + metricNamespacePrefix: "prefix", + }); + + testLogger.metricCounter({ + namespace: "namespace", + event: "no_value", + }); + + expect(getLoggerBuffer(testLogger).metrics[0]).toEqual( + expect.objectContaining({ + metricNamespace: "prefix.namespace", + }) + ); + }); }); describe("metricGauge", () => { - test("should add metrics of gauge type", () => { + test("adds metrics of gauge type", () => { const testLogger = initLogger(); testLogger.metricGauge({ @@ -331,10 +352,28 @@ describe("metricGauge", () => { }, }); }); + + test("uses metric namespace prefix", () => { + const testLogger = initLogger({ + metricNamespacePrefix: "prefix", + }); + + testLogger.metricGauge({ + namespace: "namespace", + event: "load", + value: 100, + }); + + expect(getLoggerBuffer(testLogger).metrics[0]).toEqual( + expect.objectContaining({ + metricNamespace: "prefix.namespace", + }) + ); + }); }); describe("addMetricDimensionBuilder", () => { - test("should add dimensions from builder", () => { + test("adds dimensions from builder", () => { const testLogger = initLogger(); testLogger.addMetricDimensionBuilder(() => ({ @@ -356,7 +395,7 @@ describe("addMetricDimensionBuilder", () => { ); }); - test("should overwrite existing dimensions", () => { + test("overwrites existing dimensions", () => { const testLogger = initLogger(); testLogger.addMetricDimensionBuilder(() => ({ @@ -385,7 +424,7 @@ describe("addMetricDimensionBuilder", () => { ); }); - test("should merge dimensions", () => { + test("merges dimensions", () => { const testLogger = initLogger(); testLogger.addMetricDimensionBuilder(() => ({