- Require Node.js 22.14.0+ (#283)
-
deps: dtrim 1.13.3 (#290)
This prevents a runtime error when logging objects with strict this bindings
-
types: Export
Eeeoh.Options(#274) -
Reduce bundle size (#289)
- deps: Migrate
stdoutMocktest functionality fromfast-redactto@pinojs/redact(#263)
- types: Resolve
error TS2304: Cannot find name 'exports_d_exports'.errors (#245)
-
createLogger: Redact request body in HTTP client errors (#247)
An HTTP request body may contain sensitive information. While
@seek/loggeralready avoids logging body content when it is supplied with areqorres, HTTP clients may include equivalent information in errors, creating another avenue for information exposure.@seek/loggernow automatically redacts the following property paths undererrorerror:config.bodyconfig.dataconfig.headers.user-emailresponse.config
If you currently rely on this incidental logging of request bodies for troubleshooting and you are confident that your request will never contain sensitive information, we recommend writing a separate log that includes the request body on a different property path. You can also reach out to discuss your use case.
-
Improve compatibility with ESM/Bundlers (#238)
-
deps: Switch configuration parsing library from
pure-parsetosury(#237)
-
createLogger: Include
"ddsource": "nodejs"attribute by default (#234)This applies when the
eeeohintegration is not active and improves the Datadog experience for workloads that rely on external routing configuration (e.g. via LogCentral).
-
eeeoh: Omit
ddsourceandddtagsondatadog: false(#234) -
createLogger: Avoid mutating
optsargument (#239) -
types: Make
logger.child()bindings stricter (#233)
This much-delayed release introduces an opt-in eeeoh integration for SEEK's proprietary logging solution and Datadog observability practices. It supports standard DD_ environment variables and advanced log tiering behaviour.
// process.env.DD_ENV = 'production';
// process.env.DD_SERVICE = 'my-component-name';
// process.env.DD_VERSION = 'abcdefa.123';
const logger = createLogger({
eeeoh: {
datadog: 'tin',
team: 'my-owner-name', // Optional
use: 'environment',
},
});
logger.info('Hello');
// {
// "ddsource": "nodejs",
// "ddtags": "env:production,team:my-owner-name,version:abcdefa.123",
// "eeeoh": {
// "logs": {
// "datadog": {
// "enabled": true,
// "tier": "tin"
// }
// }
// },
// "env": "production",
// "msg": "Hello",
// "service": "my-component-name",
// "version": "abcdefa.123"
// }Our new Datadog logging guidance on Backstage walks through recommendations to reduce gotchas and rework down the track.
While you don't need to upgrade overnight, we have tested the new version on multiple production components for several weeks, and more feedback will improve the Datadog experience for all 🙏
Warning
Propagating the DD_ENV environment variable to a workload container can unexpectedly change the env tag that hot-shots applies to custom metrics. If your Gantry service uses this package directly or alongside seek-datadog-custom-metrics and seek-koala, heed our Gantry logging guidance to avoid a breaking change to custom metrics and dependent resources (dashboards, monitors, etc).
-
Restrict select log attributes (#184)
When specifying attributes in a child logger or log method:
logger.child({ env }); // ~~~ logger.method({ env }, msg); // ~~~
The following keys are no longer recommended as they should be set upfront in
createLogger:Key Replacement ddsourceeeeohddtagseeeoheeeeoheeeoheeoheeeohenveeeoh: { use: 'environment' }serviceeeeoh: { use: 'environment' }versioneeeoh: { use: 'environment' }The following keys now have specific TypeScript types associated with them:
Key Type durationnumbereeeohobjectlatencynumberx-request-idstringThis change aims to drive alignment with eeeoh & Datadog conventions for an improved out-of-box experience. Reach out if these new type definitions pose problems for your application.
We also recommend reviewing our guidance on logger types and reducing coupling to the
pino.Loggertype for forward compatibility. -
Apply
errserializer toerrorkey (#184)This makes it easier to move between
logger({ err }, 'msg')andlogger({ error }, 'msg'). If your application was already sending theerrorkey, you may observe slightly different output. Seepino-std-serializersfor more information about the serializer.The
errorkey provides a better out-of-box experience in Datadog as a standard attribute. SEEK applications do not need to rewrite existingerrs at this time;@seek/loggerwill automatically re-maperrtoerrorwhen you opt in to the eeeoh integration, and we may investigate a codemod or an equivalent bulk migration option in the future. -
Restrict manual
base.eeeohconfiguration (#184)If you have an application that manually configures eeeoh routing like so:
createLogger({ base: { ddsource: 'nodejs', ddtags: `version:${process.env.VERSION || 'missing'},env:${process.env.ENVIRONMENT || 'missing'}`, service: 'my-component-name', eeeoh: { logs: { datadog: { enabled: true, tier: 'tin', }, }, }, }, });
@seek/loggerwill now treat this as a type error to encourage adoption and stronger typing of our built-in eeeoh integration. Take particular note of theuse: 'environment'prerequisites before proceeding.createLogger({ eeeoh: { datadog: 'tin', use: 'environment' }, });
The built-in integration does not support configuring a Splunk destination; you can append a Splunk destination via your LogCentral strategy.
-
createDestination: Remove
ddsource,eeeoh,envandservicewithmock: true(#218)These
mockdefaults can be overwritten; see our documentation for more information. -
Export
createLoggeras a named export (#189)This improves forward compatibility with TypeScript & ESM. While the named export is recommended, there is no immediate need to migrate existing codebases, and we've left the default export in place.
Migration:
- import createLogger from '@seek/logger'; + import { createLogger } from '@seek/logger';
-
Add eeeoh integration (#184)
See the documentation for more information.
-
Enforce stricter typing for logger methods (#182)
This is a breaking change to the types, improving type safety by enforcing stricter parameter typing on all logger methods.
Existing code that passes metadata after the message string will need to be updated. This pattern was previously silently ignoring the metadata, but now triggers a type error to prevent data loss.
Before (no longer works):
logger.error('my message', { err, metadata });
In this pattern, any metadata passed after the message string is not captured by the logger.
After (correct usage):
logger.error({ err, metadata }, 'my message');
This ensures all metadata is properly captured and logged.
-
Drop support for Node.js 18.x (#181)
Node.js 18 reached EOL in April 2025. The minimum supported version is now Node.js 20.9.0.
- createDestination: Tweak returned
destinationtype (#177)
-
Add support for configuring custom log levels: (#164)
import createLogger from '@seek/logger'; const logger = createLogger({ name: 'my-app', customLevels: { foo: 35, }, }); logger.foo('Bar');
-
Apply trimming to serializers (#143)
Previously, built-in serializers and custom ones supplied via the
serializersoption were not subject to trimming. This caused some emitted error logs to be extremely large.Now, trimming is applied across all serializers by default. If you rely on deeply nested
errproperties to troubleshoot your application, tune themaxObjectDepthconfigured on your logger.
-
createDestination: Use
Recordtype forstdoutMock.callsandstdoutMock.onlyCall()(#137)This allows you to destructure a call in your test code without the TypeScript compiler complaining:
const { level, ...rest } = stdoutMock.onlyCall();
-
createDestination: Implement logging integration testing (#134)
@seek/loggernow bundles a convenient mechanism for recording logging calls, built on Pino's support for customisable destinations. See docs/testing.md for more information.
- deps: pino-std-serializers ^7.0.0 (#130)
-
deps: pino 9 (#128)
Our minimum Node.js version is now 18.18.
-
Add default redact paths (#123)
@seek/loggernow redacts a set of built-in paths by default.These default paths cannot be disabled, and are concatenated to custom redact paths provided via
redact: ['custom.path']orredact: { paths: ['custom.path'] }.
-
deps: fast-redact ^3.5.0 (#119)
The mutation proof of concept that led us to pin v3.3.0 has been fixed in fast-redact@3.4.1:
const logger = createLogger({ redact: { censor: '???', paths: ['props.*'] }, }); const props = { name: 'PII' }; logger.child({ props }); logger.child({ props }); console.log({ props }); // { props: { name: 'PII' } }
The
TypeErrorproof of concept reported in #14 has been fixed in fast-redact@3.5.0.
-
deps: Pin
fast-redact@3.3.0(#114)This aims to discourage adoption of
fast-redact@3.4.0as it mutates input data when you:- Write application logs with
@seek/loggerorpino - Configure the
redactoption with wildcards - Use the logger in a slightly strange way, such as calling
.child()with the same props more than once
const logger = createLogger({ redact: { censor: '???', paths: ['props.*'] }, }); const props = { name: 'PII' }; logger.child({ props }); logger.child({ props }); console.log({ props }); // { props: { name: '???' } }
If you suspect that your project meets these criteria, consider reviewing your lock file to ensure that
fast-redact@3.4.0is not installed before merging this upgrade or a subsequent lock file maintenance PR. - Write application logs with
-
Omit request headers (#92)
@seek/loggernow omits the following properties fromheadersandreq.headersby default:x-envoy-attempt-countx-envoy-decorator-operationx-envoy-expected-rq-timeout-msx-envoy-external-addressx-envoy-internalx-envoy-peer-metadatax-envoy-peer-metadata-idx-envoy-upstream-service-time
To opt out of this behaviour, provide an empty list or your own list of omissible request headers to
omitHeaderNames:const logger = createLogger({ name: 'my-app', + omitHeaderNames: ['dnt', 'sec-fetch-dest'], });You can also extend the default list like so:
- import createLogger from '@seek/logger'; + import createLogger, { DEFAULT_OMIT_HEADER_NAMES } from '@seek/logger'; const logger = createLogger({ name: 'my-app', + omitHeaderNames: [...DEFAULT_OMIT_HEADER_NAMES, 'dnt', 'sec-fetch-dest'] });