|
| 1 | ++++ |
| 2 | +ShowToc = true |
| 3 | +date = 2022-09-06T18:30:00Z |
| 4 | +description = "Brief intro to winston transports and how to create custom ones." |
| 5 | +tags = ["webdev", "winston", "logging", "custom"] |
| 6 | +title = "Winston Transports??" |
| 7 | +[cover] |
| 8 | +alt = "winston transport blog post cover" |
| 9 | +image = "/blog/uploads/winston-transport-cover.png" |
| 10 | ++++ |
| 11 | + |
| 12 | +### Brief Introduction to what is `winston`? |
| 13 | + |
| 14 | +> Winston is a node package that provides a simple and universal logging library. It supports **multiple transports**, such as file, console, and syslog. Winston is easy to use and can be **customized** to meet your specific needs. |
| 15 | +> |
| 16 | +
|
| 17 | +Did you see the words `multiple transports` and `customized` in the above definition of `winston` (that I asked Google Bard to write)? Yeah, `winston` is probable the most sophisticated and customizable logger out there. |
| 18 | + |
| 19 | +### What are transports? |
| 20 | + |
| 21 | +So we know that `winston` supports multiple transports, but what is a transport anyway? |
| 22 | + |
| 23 | +> In `winston`, transport is essentially a storage device for your logs. Each instance of a `winston` logger can have multiple transports configured at different levels. |
| 24 | +> |
| 25 | +
|
| 26 | +So transport is basically like where you want to store your logs. |
| 27 | + |
| 28 | +There are some most basic ones like: |
| 29 | + |
| 30 | +- **The Console** |
| 31 | + |
| 32 | + ```tsx |
| 33 | + import winston from "winston" |
| 34 | + |
| 35 | + export const logger = winston.createLogger( |
| 36 | + { |
| 37 | + transports: [ |
| 38 | + new winston.transports.Console() |
| 39 | + ], |
| 40 | + } |
| 41 | + ) |
| 42 | + ``` |
| 43 | + |
| 44 | +- **Files** |
| 45 | + |
| 46 | + ```tsx |
| 47 | + ... |
| 48 | + new winston.transports.File({ filename: "logs/all.log" }) |
| 49 | + ... |
| 50 | + ``` |
| 51 | + |
| 52 | + |
| 53 | +Console and file are like the most basic ones, Console basically prints your logs to the console and file one just stores your log in the defined file. You can go crazy with the options and do a lot more stuff, like storing logs of only a specific `level`, let’s say `error` or something. |
| 54 | + |
| 55 | +The default ones are great, and they make for the most basic use cases, but if you’re going into production and logs are just more than something you’ll use to debug and get HTTP status codes. |
| 56 | + |
| 57 | +There are a lot of platforms that allows you to store your logs and do crazy things with them (basically alerts and analytics). Some of them are [Logtail](https://betterstack.com/logtail), and an open source one is [Highstorm](https://highstorm.app). |
| 58 | + |
| 59 | +To upload your logs to them, you’ll need custom transport. `winston` give you the power to create custom transports pretty easily with the `winston-transport` package, and here’s how you do it… |
| 60 | + |
| 61 | +### Custom Transports |
| 62 | + |
| 63 | +So basically custom transports are to upload your logs to some sort of storage or maybe do something else with it, like creating alerts and stuff. |
| 64 | + |
| 65 | +Here’s how you create basic custom transport for `winston`: |
| 66 | + |
| 67 | +```tsx |
| 68 | +// my-transport.ts |
| 69 | +
|
| 70 | +import Transport, { TransportStreamOptions } 'winston-transport'; |
| 71 | +import type { LogEntry } from "winston"; |
| 72 | +
|
| 73 | +export class MyTransport extends Transport { |
| 74 | + constructor( |
| 75 | + opts: TransportStreamOptions |
| 76 | + ) { |
| 77 | + super(opts); |
| 78 | +
|
| 79 | + /* |
| 80 | + * Consume any custom options here. e.h: |
| 81 | + * Connection information for databases |
| 82 | + * Authentication information for APIs |
| 83 | + */ |
| 84 | + } |
| 85 | +
|
| 86 | + // this functions run when something is logged so here's where you can add you custom logic to do stuff when something is logged. |
| 87 | + log(info: LogEntry, callback: any) { |
| 88 | + // make sure you installed `@types/node` or this will give a typerror |
| 89 | + // this is the basic default behavior don't forget to add this. |
| 90 | + setImmediate(() => { |
| 91 | + this.emit("logged", info); |
| 92 | + }); |
| 93 | +
|
| 94 | + const { level, message, ...meta } = info; |
| 95 | +
|
| 96 | + // here you can add your custom logic, e.g. ingest data into database etc. |
| 97 | +
|
| 98 | + // don't forget this one |
| 99 | + callback(); |
| 100 | + } |
| 101 | +} |
| 102 | +``` |
| 103 | + |
| 104 | +Now you can add your custom transport very easily as: |
| 105 | + |
| 106 | +```tsx |
| 107 | +// logger.ts |
| 108 | +
|
| 109 | +import {MyTransport} from "./my-transport.ts" |
| 110 | +
|
| 111 | +const options = { |
| 112 | + // custom transport options |
| 113 | +} |
| 114 | +
|
| 115 | +const myTransport = new MyTransport(options) |
| 116 | +
|
| 117 | +export const logger = winston.createLogger({ |
| 118 | + ... |
| 119 | + transports: [ |
| 120 | + ... |
| 121 | + mytransport, |
| 122 | + ... |
| 123 | + ] |
| 124 | +}); |
| 125 | +``` |
| 126 | + |
| 127 | +Pretty easy to write, yup, thanks to `winston` being the best logger out there with this level of customization. With the above example, you can create any custom transport you want with whatever fancy logic you want. |
| 128 | + |
| 129 | +Check out these to dive deeper: |
| 130 | + |
| 131 | +[npm: winston-transport](https://www.npmjs.com/package/winston-transport) |
| 132 | + |
| 133 | +[npm: winston](https://www.npmjs.com/package/winston) |
| 134 | + |
| 135 | +Here are some packages that provide transports to do various things (mostly upload to their service): |
| 136 | + |
| 137 | +[npm: @logtail/winston](https://www.npmjs.com/package/@logtail/winston) |
| 138 | + |
| 139 | +[npm: winston-transport-sentry-node](https://www.npmjs.com/package/winston-transport-sentry-node) |
| 140 | + |
| 141 | +[npm: winston-kafka-transport](https://www.npmjs.com/package/winston-kafka-transport) |
| 142 | + |
| 143 | +[npm: @shelf/winston-datadog-logs-transport](https://www.npmjs.com/package/@shelf/winston-datadog-logs-transport) |
0 commit comments