Compare

evlog vs Winston: formats and request events

Compare Winston formats, transports, and custom levels with evlog event accumulation before migrating an existing application.

Your Winston configuration may encode years of operational decisions: which fields reach a backend, which errors trigger alerts, and which transports receive each severity. Start a migration by preserving those decisions.

At a glance

Winstonevlog
Core modelEach call writes an info object through a format chain to one or more transportsIndividual structured logs, plus an operation logger that accumulates fields and emits one event
Output shapingComposable formats from logform (combine, json, printf, custom formats)Event fields set by the application, plugins and enrichers, then drain serialization
DestinationsCore Console, File and Http transports, plus community transportsDrain adapters such as Axiom, OTLP, Sentry, PostHog, Datadog and Better Stack
Levelsnpm levels by default (error to silly), or custom levelsFixed severities, with sampling for wide events
Process failuresexceptionHandlers and rejectionHandlersRequest errors become structured error events; process handlers stay your choice
ExtrasProfiling, querying and streaming logs from some transportsStructured errors with why, fix and link

Sources: the Winston README sections on formats, logging levels, transports, exceptions, rejections and profiling.

Identify what the configuration already does

Winston composes formats through logform, supports custom levels, and configures multiple transports with their own levels. It also offers child loggers, profiling, and exception/rejection handlers. JSON output is available through format.json(). These are reasons to retain it when the pipeline already works. See the Winston documentation.

Existing requirementWhat to check in evlog
Custom levelsMap them to four severities and update queries or alerts that depend on the original values.
Format chainDecide which transformations become context fields, plugin hooks, or drain serialization.
Custom transportFind a matching drain or port the protocol and delivery behavior.
Per-transport levelPreserve destination-specific filtering explicitly in the delivery configuration.
Exception/rejection handlerKeep process-level failure handling separate from an individual request's error event.

Decide who assembles the final event

Winston can log a completed object once. The application decides how to collect it. evlog's createLogger() provides that accumulator, set() adds context, and emit() produces the final event. Framework integrations manage that operation lifecycle.

Use Wide Events to decide whether this model removes code from your handlers. It does not automatically preserve a Winston output schema, and changing several records into one may require new dashboard queries.

Migrate with observable checkpoints

Choose one operation and document the output fields consumers require. Configure an evlog drain adapter, then exercise success and failure against a test destination. Confirm that redaction, severity mapping, retries, and process shutdown meet the same requirements as the existing path.

Keep Winston when format composition or custom transports already solve the problem. Consider evlog when accumulated context, structured errors, and its integration lifecycle reduce application code. Neither a library's age nor unequal-output benchmarks establish which is better for your workload. The Performance reference explains the measurements to compare.

FAQ

Is evlog a drop-in replacement for Winston? No. Call signatures, levels and the output envelope differ. Plan the migration around the fields that dashboards and alerts depend on.

Can I keep Winston and add evlog? Yes. A common split is to keep Winston for existing transports and adopt evlog request events on new routes, as long as both don't forward the same records to the same backend.

Which one is faster? This page makes no performance claim. Compare both on your own workload with equivalent output, as described in the Performance reference.

Use the logger overview to compare the other options before expanding a migration.