Winston Logs installation
Contents
Send your existing Winston logs to PostHog with the OpenTelemetry Winston instrumentation. You don't need to change your logger calls. Requires Winston v3.
- 1
Install OpenTelemetry packages
RequiredTerminalThe instrumentation only sends logs when
@opentelemetry/winston-transportis installed. - 2
Get your project token
RequiredYou'll need your PostHog project token to authenticate log requests. This is the same key you use for capturing events and exceptions with the PostHog SDK.
Important: Use your project token which starts with
phc_. Do not use a personal API key (which starts withphx_).You can find your project token in Project Settings.
- 3
Create an instrumentation file
RequiredCreate an
instrumentation.jsfile. It starts the OpenTelemetry SDK and tells it to send every Winston log to PostHog.instrumentation.jsIf your app already handles
SIGTERM(for example, to drain open requests), don't add a second handler. Exportsdkand callawait sdk.shutdown()at the end of your existing shutdown code instead. - 4
Load the instrumentation before your app
RequiredThe instrumentation must load before your app imports
winston. Otherwise it can't patch Winston and no logs are sent. Use the--requireflag when you start your app:TerminalIf you can't change the start command (for example, on a hosting platform), set
NODE_OPTIONSinstead:TerminalIf your app uses ES modules
--requiredoesn't patchimportstatements. Install the OpenTelemetry instrumentation package:TerminalName the file
instrumentation.mjs, change therequirecalls toimportstatements, and register the OpenTelemetry loader hook before you start the SDK:instrumentation.mjsThen start your app with
--import:Terminal - 5
Use your Winston logger
RequiredKeep using Winston as before. Your existing transports still work, and a copy of each log goes to PostHog:
JavaScriptPostHog receives each Winston record like this:
Winston PostHog Logs Message Log body Level ( info,warn,error, etc.)Severity Metadata, defaultMeta, and child logger fieldsLog attributes ErrorobjectsError message appended to the body, a stackattribute, andexception.type,exception.message, andexception.stacktraceattributesLogs below the logger's
levelare not sent. In the example above,logger.debug()calls don't reach PostHog.To link logs to a person and their session replay, add the
posthogDistinctIdandsessionIdfields. A child logger adds them to every log in a request:JavaScript - 6
Next steps
CheckpointWhat you can do with your logsAction Description Why you need logs What logs show you that nothing else does Search logs Use the search interface to find specific log entries Filter by level Filter by INFO,WARN,ERROR, etc.Link session replay Connect logs to users and session replays by passing posthogDistinctIdandsessionIdLink logs to a person Surface every log emitted on behalf of a user on their PostHog person profile Logging best practices Learn what to log, how to structure logs, and patterns that make logs useful in production
Troubleshooting
Logs not appearing in PostHog
- Check that
@opentelemetry/winston-transportis installed. Without it, the instrumentation doesn't send logs. - Make sure the instrumentation file loads before
winston. If your app uses ES modules, you need the--importflag and the loader hook. - Check your Winston version. Log sending requires Winston v3.
- The SDK sends logs in batches, so a short-lived script that ends on its own loses the last batch. Add
module.exports = sdk;toinstrumentation.jsand callawait require('./instrumentation').shutdown()before the script ends.
For general Logs troubleshooting (authentication, connection issues, format problems), see the Logs troubleshooting guide.











