Skip to content

Commit

Permalink
feat: add new metric helpers for counters and gauges (#80)
Browse files Browse the repository at this point in the history
  • Loading branch information
wsbrunson authored Feb 13, 2024
1 parent 511dc42 commit 57c29db
Show file tree
Hide file tree
Showing 4 changed files with 164 additions and 3 deletions.
44 changes: 42 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,38 @@ For example:

Call this to attach general tracking information to the current page. This is useful if the data is not associated with a specific event, and will be sent to the server the next time the logs are flushed.

### `$logger.metric(<event>, <payload>);`
### `$logger.metricCounter(<event>, <payload>);`

Queues a metric
Queues a counter metric, helper wrapping `logger.metric`

```
logger.metricCounter({
namespace: "pp.team.product.feature",
event: "button_click",
dimensions: {
type: "paypal"
}
})
```

### `$logger.metricGauge(<event>, <payload>);`

Queues a gauge metric, helper wrapping `logger.metric`

```
logger.metricGauge({
namespace: "pp.team.product.feature",
event: "request_latency",
value: 100,
dimensions: {
method: "GET"
}
})
```

### Deprecated - `$logger.metric(<event>, <payload>);`

Queues a metric. We suggest using the `metricCount` or `metricGauge` interface for better type safety and clearer intention in your code.

## Advanced

Expand All @@ -60,6 +89,17 @@ $logger.addMetaBuilder(function () {
});
```

### `$logger.addMetricDimensionBuilder(<function>);`

Attach a method which is called and will attach values to **each metric's dimensions** whenever the logs are flushed

```javascript
$logger.addMetricDimensionBuilder(() => ({
token_used: true,
type: "user_id_token",
}));
```

### `$logger.addPayloadBuilder(<function>);`

Attach a method which is called and will attach values to **each individual log's payload** whenever the logs are flushed
Expand Down
31 changes: 30 additions & 1 deletion src/logger.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,12 @@ import {
import { LOG_LEVEL, PROTOCOL } from "./constants";
import { extendIfDefined } from "./util";
import { type Transport, getHTTPTransport } from "./http";
import type { MetricPayload, Payload } from "./types";
import type {
MetricPayload,
Payload,
MetricPayloadCounter,
MetricPayloadGauge,
} from "./types";

type LoggerOptions = {|
url?: string,
Expand Down Expand Up @@ -50,6 +55,8 @@ export type LoggerType = {|

track: Track,
metric: LogMetric,
metricCounter: (payload: MetricPayloadCounter) => LoggerType,
metricGauge: (payload: MetricPayloadGauge) => LoggerType,

flush: () => ZalgoPromise<void>,
immediateFlush: () => ZalgoPromise<void>,
Expand Down Expand Up @@ -298,6 +305,26 @@ export function Logger({
return logger; // eslint-disable-line no-use-before-define
}

function metricCounter(metricPayload: MetricPayloadCounter): LoggerType {
return metric({
metricNamespace: metricPayload.namespace,
metricEventName: metricPayload.event,
metricValue: metricPayload.value ?? 1,
metricType: "counter",
dimensions: metricPayload.dimensions,
});
}

function metricGauge(metricPayload: MetricPayloadGauge): LoggerType {
return metric({
metricNamespace: metricPayload.namespace,
metricEventName: metricPayload.event,
metricValue: metricPayload.value,
metricType: "gauge",
dimensions: metricPayload.dimensions,
});
}

function setTransport(newTransport: Transport): LoggerType {
transport = newTransport;
return logger; // eslint-disable-line no-use-before-define
Expand Down Expand Up @@ -356,6 +383,8 @@ export function Logger({
error,
track,
metric,
metricCounter,
metricGauge,
flush,
immediateFlush,
addPayloadBuilder,
Expand Down
68 changes: 68 additions & 0 deletions src/logger.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,74 @@ describe("beaver logger provides flushing methods that send events to the server
});
});

describe("metricCounter", () => {
test("should add metrics of counter type", () => {
const testLogger = initLogger();

testLogger.metricCounter({
namespace: "namespace",
event: "no_value",
dimensions: {
one: "1",
},
});

testLogger.metricCounter({
namespace: "namespace",
event: "value",
value: 3,
dimensions: {
one: "1",
},
});

expect(getLoggerBuffer(testLogger).metrics[0]).toEqual({
metricNamespace: "namespace",
metricEventName: "no_value",
metricValue: 1,
metricType: "counter",
dimensions: {
one: "1",
},
});

expect(getLoggerBuffer(testLogger).metrics[1]).toEqual({
metricNamespace: "namespace",
metricEventName: "value",
metricValue: 3,
metricType: "counter",
dimensions: {
one: "1",
},
});
});
});

describe("metricGauge", () => {
test("should add metrics of gauge type", () => {
const testLogger = initLogger();

testLogger.metricGauge({
namespace: "namespace",
event: "load",
value: 100,
dimensions: {
one: "1",
},
});

expect(getLoggerBuffer(testLogger).metrics[0]).toEqual({
metricNamespace: "namespace",
metricEventName: "load",
metricValue: 100,
metricType: "gauge",
dimensions: {
one: "1",
},
});
});
});

describe("addMetricDimensionBuilder", () => {
test("should add dimensions from builder", () => {
const testLogger = initLogger();
Expand Down
24 changes: 24 additions & 0 deletions src/types.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,27 @@ export type MetricPayload = {|
*/
dimensions?: { [string]: mixed },
|};

export type MetricPayloadCounter = {|
namespace: string, // the name of the metric that's used for charting / finding in signalFx
event: string, // assigned to event_name dimension in signalFx
value?: number, // in most cases this will be 1 if we want to count 1 instance of an event happening.
/**
* For proper usage & best practices guidance around dimensions please read: -------------------->
* - https://engineering.paypalcorp.com/confluence/pages/viewpage.action?pageId=981633893
* - https://engineering.paypalcorp.com/confluence/display/Checkout/Checkout+Observability+Overview
*/
dimensions?: { [string]: mixed },
|};

export type MetricPayloadGauge = {|
namespace: string, // the name of the metric that's used for charting / finding in signalFx
event: string, // assigned to event_name dimension in signalFx
value: number, // in most cases this will be 1 if we want to count 1 instance of an event happening.
/**
* For proper usage & best practices guidance around dimensions please read: -------------------->
* - https://engineering.paypalcorp.com/confluence/pages/viewpage.action?pageId=981633893
* - https://engineering.paypalcorp.com/confluence/display/Checkout/Checkout+Observability+Overview
*/
dimensions?: { [string]: mixed },
|};

0 comments on commit 57c29db

Please sign in to comment.