dlogify docs

Redaction

Remove sensitive data in your process, before your logs reach dlogify.

By the end of this page, your Node.js application removes the data you choose before its logs leave the process.

dlogify always redacts what it receives (What is sent). Redaction in your process is an extra layer you control: the data you name never travels at all.

Without code changes

Set these variables for register or logify run:

LOGIFY_REDACT_DEFAULTS=1                # apply dlogify's rules in your process
LOGIFY_REDACT_KEYS=customer_ref,ssn     # attributes whose values are replaced by <redacted>

LOGIFY_REDACT_DEFAULTS uses the same rules and placeholders as dlogify (<email>, <secret>, <card>, <ip>, <jwt>), so your error groups look the same either way.

With the SDK

logify.ts
import { createHash } from "node:crypto";
import * as logify from "@dlogify/node";

logify.init({
  service: "checkout",
  // dlogify's own rules, applied before records leave your process.
  redactDefaults: true,
  // Attributes whose values never leave your process.
  redactKeys: ["customer_ref", /^x-internal-/i],
  // Your own formats.
  redactPatterns: [/\bMRN-\d{8}\b/g, { pattern: /acct_[a-z0-9]+/gi, replacement: "<account>" }],
  beforeSend(event) {
    // Drop health checks.
    if (event.attributes.route === "/healthz") return null;
    // Keep a reference you can search for, without the value itself.
    if (typeof event.attributes.user_id === "string") {
      event.attributes.user_id = createHash("sha256").update(event.attributes.user_id).digest("hex").slice(0, 16);
    }
    return event;
  },
});

Records go through, in order:

  1. redactKeys: an attribute whose key matches (exact name, any case, or a regular expression) is replaced by <redacted>.
  2. redactPatterns: each match in the message and in text attributes is replaced by <redacted>, or by the replacement you give, taken literally.
  3. redactDefaults: dlogify's rules.
  4. beforeSend: your function receives the event (level, message, attributes, scope, time) and returns it, changed or not, or null to drop it. Changes to level, scope and time are ignored.

The process's own attributes (service, environment, release, the attributes given to init()) are not redacted.

pino

The pino transport runs in its own worker, so it does not use the options you pass to init(). Give it the rules in the transport options, or use the environment variables:

pino({ transport: { target: "@dlogify/node/pino", options: { redactDefaults: true, redactKeys: ["customer_ref"] } } });

beforeSend is not available with the pino transport: functions cannot be passed to the worker. winston uses the init() client and gets every option.

When beforeSend fails

If beforeSend throws, returns a Promise or returns something that is not an event, the record is dropped, never sent unredacted. The first failure is printed on stderr; set LOGIFY_DEBUG=1 to count the rest. beforeSend must be synchronous, and a record you log from inside it is dropped. An invalid option, such as a pattern that is not a regular expression, is ignored with a warning on stderr.

Cost

Rules run once per record, when it is logged, for records at or above minLevel. A typical record takes a few microseconds. Without any of these options, nothing runs.

OpenTelemetry Collector

The Collector presets do not use these options. Use the Collector's transform processor to change records before they are exported.

On this page