@contrast/agent 4.16.1 → 4.17.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (267) hide show
  1. package/bin/VERSION +1 -1
  2. package/bin/linux/contrast-service +0 -0
  3. package/bin/mac/contrast-service +0 -0
  4. package/bin/windows/contrast-service.exe +0 -0
  5. package/esm.mjs +21 -11
  6. package/lib/assess/policy/propagators.json +4 -0
  7. package/lib/assess/policy/signatures.json +5 -0
  8. package/lib/assess/propagators/fastify-static/allowed-path.js +85 -0
  9. package/lib/cli-rewriter/index.js +1 -1
  10. package/lib/contrast.js +1 -1
  11. package/lib/core/rewrite/index.js +2 -2
  12. package/lib/protect/rules/cmd-injection/cmdinjection-rule.js +1 -1
  13. package/lib/protect/service.js +2 -0
  14. package/lib/util/trace-util.js +5 -4
  15. package/node_modules/@colors/colors/LICENSE +26 -0
  16. package/node_modules/@colors/colors/README.md +219 -0
  17. package/node_modules/@colors/colors/examples/normal-usage.js +83 -0
  18. package/node_modules/@colors/colors/examples/safe-string.js +80 -0
  19. package/node_modules/@colors/colors/index.d.ts +136 -0
  20. package/node_modules/@colors/colors/lib/colors.js +211 -0
  21. package/node_modules/@colors/colors/lib/custom/trap.js +46 -0
  22. package/node_modules/@colors/colors/lib/custom/zalgo.js +110 -0
  23. package/node_modules/@colors/colors/lib/extendStringPrototype.js +110 -0
  24. package/node_modules/@colors/colors/lib/index.js +13 -0
  25. package/node_modules/@colors/colors/lib/maps/america.js +10 -0
  26. package/node_modules/@colors/colors/lib/maps/rainbow.js +12 -0
  27. package/node_modules/@colors/colors/lib/maps/random.js +11 -0
  28. package/node_modules/@colors/colors/lib/maps/zebra.js +5 -0
  29. package/node_modules/@colors/colors/lib/styles.js +95 -0
  30. package/node_modules/@colors/colors/lib/system/has-flag.js +35 -0
  31. package/node_modules/@colors/colors/lib/system/supports-colors.js +151 -0
  32. package/node_modules/@colors/colors/package.json +49 -0
  33. package/node_modules/@colors/colors/safe.d.ts +48 -0
  34. package/node_modules/@colors/colors/safe.js +10 -0
  35. package/node_modules/@colors/colors/themes/generic-logging.js +12 -0
  36. package/node_modules/@dabh/diagnostics/README.md +16 -16
  37. package/node_modules/@dabh/diagnostics/package.json +9 -9
  38. package/node_modules/async/CHANGELOG.md +13 -0
  39. package/node_modules/async/all.js +74 -9
  40. package/node_modules/async/allLimit.js +3 -3
  41. package/node_modules/async/allSeries.js +3 -3
  42. package/node_modules/async/any.js +75 -9
  43. package/node_modules/async/anyLimit.js +3 -3
  44. package/node_modules/async/anySeries.js +3 -3
  45. package/node_modules/async/applyEach.js +2 -2
  46. package/node_modules/async/applyEachSeries.js +2 -2
  47. package/node_modules/async/asyncify.js +3 -3
  48. package/node_modules/async/auto.js +81 -15
  49. package/node_modules/async/autoInject.js +30 -4
  50. package/node_modules/async/cargo.js +1 -1
  51. package/node_modules/async/cargoQueue.js +1 -1
  52. package/node_modules/async/compose.js +1 -1
  53. package/node_modules/async/concat.js +72 -4
  54. package/node_modules/async/concatLimit.js +3 -3
  55. package/node_modules/async/concatSeries.js +2 -2
  56. package/node_modules/async/detect.js +43 -8
  57. package/node_modules/async/detectLimit.js +3 -3
  58. package/node_modules/async/detectSeries.js +3 -3
  59. package/node_modules/async/dir.js +1 -1
  60. package/node_modules/async/dist/async.js +1379 -168
  61. package/node_modules/async/dist/async.min.js +1 -1
  62. package/node_modules/async/dist/async.mjs +1372 -161
  63. package/node_modules/async/doDuring.js +3 -3
  64. package/node_modules/async/doUntil.js +2 -2
  65. package/node_modules/async/doWhilst.js +3 -3
  66. package/node_modules/async/during.js +3 -3
  67. package/node_modules/async/each.js +69 -28
  68. package/node_modules/async/eachLimit.js +4 -4
  69. package/node_modules/async/eachOf.js +85 -16
  70. package/node_modules/async/eachOfLimit.js +3 -3
  71. package/node_modules/async/eachOfSeries.js +2 -2
  72. package/node_modules/async/eachSeries.js +2 -2
  73. package/node_modules/async/ensureAsync.js +2 -2
  74. package/node_modules/async/every.js +74 -9
  75. package/node_modules/async/everyLimit.js +3 -3
  76. package/node_modules/async/everySeries.js +3 -3
  77. package/node_modules/async/filter.js +49 -9
  78. package/node_modules/async/filterLimit.js +3 -3
  79. package/node_modules/async/filterSeries.js +3 -3
  80. package/node_modules/async/find.js +43 -8
  81. package/node_modules/async/findLimit.js +3 -3
  82. package/node_modules/async/findSeries.js +3 -3
  83. package/node_modules/async/flatMap.js +72 -4
  84. package/node_modules/async/flatMapLimit.js +3 -3
  85. package/node_modules/async/flatMapSeries.js +2 -2
  86. package/node_modules/async/foldl.js +87 -11
  87. package/node_modules/async/foldr.js +2 -2
  88. package/node_modules/async/forEach.js +69 -28
  89. package/node_modules/async/forEachLimit.js +4 -4
  90. package/node_modules/async/forEachOf.js +85 -16
  91. package/node_modules/async/forEachOfLimit.js +3 -3
  92. package/node_modules/async/forEachOfSeries.js +2 -2
  93. package/node_modules/async/forEachSeries.js +2 -2
  94. package/node_modules/async/forever.js +4 -4
  95. package/node_modules/async/groupBy.js +62 -8
  96. package/node_modules/async/groupByLimit.js +3 -3
  97. package/node_modules/async/groupBySeries.js +2 -2
  98. package/node_modules/async/inject.js +87 -11
  99. package/node_modules/async/internal/applyEach.js +2 -2
  100. package/node_modules/async/internal/asyncEachOfLimit.js +1 -1
  101. package/node_modules/async/internal/consoleFunc.js +5 -1
  102. package/node_modules/async/internal/createTester.js +2 -2
  103. package/node_modules/async/internal/eachOfLimit.js +6 -6
  104. package/node_modules/async/internal/filter.js +2 -2
  105. package/node_modules/async/internal/iterator.js +5 -2
  106. package/node_modules/async/internal/map.js +1 -1
  107. package/node_modules/async/internal/parallel.js +3 -3
  108. package/node_modules/async/internal/queue.js +4 -4
  109. package/node_modules/async/internal/reject.js +2 -2
  110. package/node_modules/async/internal/setImmediate.js +6 -2
  111. package/node_modules/async/internal/wrapAsync.js +1 -1
  112. package/node_modules/async/log.js +1 -1
  113. package/node_modules/async/map.js +86 -6
  114. package/node_modules/async/mapLimit.js +3 -3
  115. package/node_modules/async/mapSeries.js +3 -3
  116. package/node_modules/async/mapValues.js +102 -12
  117. package/node_modules/async/mapValuesLimit.js +4 -4
  118. package/node_modules/async/mapValuesSeries.js +1 -1
  119. package/node_modules/async/memoize.js +3 -3
  120. package/node_modules/async/nextTick.js +3 -3
  121. package/node_modules/async/package.json +4 -6
  122. package/node_modules/async/parallel.js +96 -7
  123. package/node_modules/async/parallelLimit.js +2 -2
  124. package/node_modules/async/priorityQueue.js +11 -4
  125. package/node_modules/async/queue.js +4 -4
  126. package/node_modules/async/race.js +3 -3
  127. package/node_modules/async/reduce.js +87 -11
  128. package/node_modules/async/reduceRight.js +2 -2
  129. package/node_modules/async/reflect.js +2 -2
  130. package/node_modules/async/reflectAll.js +1 -1
  131. package/node_modules/async/reject.js +44 -10
  132. package/node_modules/async/rejectLimit.js +3 -3
  133. package/node_modules/async/rejectSeries.js +3 -3
  134. package/node_modules/async/retry.js +2 -2
  135. package/node_modules/async/retryable.js +4 -4
  136. package/node_modules/async/select.js +49 -9
  137. package/node_modules/async/selectLimit.js +3 -3
  138. package/node_modules/async/selectSeries.js +3 -3
  139. package/node_modules/async/seq.js +4 -4
  140. package/node_modules/async/series.js +112 -12
  141. package/node_modules/async/setImmediate.js +1 -1
  142. package/node_modules/async/some.js +75 -9
  143. package/node_modules/async/someLimit.js +3 -3
  144. package/node_modules/async/someSeries.js +3 -3
  145. package/node_modules/async/sortBy.js +121 -19
  146. package/node_modules/async/timeout.js +2 -2
  147. package/node_modules/async/times.js +1 -1
  148. package/node_modules/async/timesLimit.js +3 -3
  149. package/node_modules/async/timesSeries.js +1 -1
  150. package/node_modules/async/transform.js +111 -19
  151. package/node_modules/async/tryEach.js +3 -3
  152. package/node_modules/async/until.js +3 -3
  153. package/node_modules/async/waterfall.js +4 -4
  154. package/node_modules/async/whilst.js +3 -3
  155. package/node_modules/async/wrapSync.js +3 -3
  156. package/node_modules/color/README.md +9 -0
  157. package/node_modules/color/index.js +4 -1
  158. package/node_modules/color/package.json +8 -8
  159. package/node_modules/color-string/README.md +6 -2
  160. package/node_modules/color-string/index.js +21 -13
  161. package/node_modules/color-string/package.json +4 -4
  162. package/node_modules/colorspace/package.json +5 -5
  163. package/node_modules/fecha/dist/fecha.min.js +1 -1
  164. package/node_modules/fecha/dist/fecha.min.js.map +1 -0
  165. package/node_modules/fecha/lib/fecha.d.ts +2 -2
  166. package/node_modules/fecha/lib/fecha.js +35 -18
  167. package/node_modules/fecha/lib/fecha.js.map +1 -0
  168. package/node_modules/fecha/lib/fecha.umd.js +35 -18
  169. package/node_modules/fecha/lib/fecha.umd.js.map +1 -0
  170. package/node_modules/fecha/package.json +9 -10
  171. package/node_modules/fecha/src/fecha.ts +524 -0
  172. package/node_modules/logform/.eslintrc +1 -1
  173. package/node_modules/logform/CHANGELOG.md +24 -0
  174. package/node_modules/logform/README.md +15 -17
  175. package/node_modules/logform/browser.js +3 -1
  176. package/node_modules/logform/cli.js +1 -1
  177. package/node_modules/logform/colorize.js +2 -2
  178. package/node_modules/logform/dist/browser.js +8 -2
  179. package/node_modules/logform/dist/cli.js +2 -2
  180. package/node_modules/logform/dist/colorize.js +5 -5
  181. package/node_modules/logform/dist/errors.js +1 -1
  182. package/node_modules/logform/dist/format.js +9 -5
  183. package/node_modules/logform/dist/index.js +53 -20
  184. package/node_modules/logform/dist/json.js +7 -6
  185. package/node_modules/logform/dist/logstash.js +1 -1
  186. package/node_modules/logform/dist/pad-levels.js +4 -4
  187. package/node_modules/logform/dist/printf.js +1 -1
  188. package/node_modules/logform/dist/simple.js +1 -1
  189. package/node_modules/logform/dist/splat.js +2 -2
  190. package/node_modules/logform/dist/uncolorize.js +1 -1
  191. package/node_modules/logform/errors.js +1 -1
  192. package/node_modules/logform/index.d.ts +36 -0
  193. package/node_modules/logform/index.js +19 -20
  194. package/node_modules/logform/json.js +7 -7
  195. package/node_modules/logform/logstash.js +1 -1
  196. package/node_modules/logform/package.json +10 -9
  197. package/node_modules/logform/simple.js +1 -1
  198. package/node_modules/logform/uncolorize.js +1 -1
  199. package/node_modules/safe-stable-stringify/CHANGELOG.md +75 -0
  200. package/node_modules/safe-stable-stringify/LICENSE +21 -0
  201. package/node_modules/safe-stable-stringify/esm/package.json +4 -0
  202. package/node_modules/safe-stable-stringify/esm/wrapper.js +6 -0
  203. package/node_modules/safe-stable-stringify/index.d.ts +18 -0
  204. package/node_modules/safe-stable-stringify/index.js +618 -0
  205. package/node_modules/safe-stable-stringify/package.json +69 -0
  206. package/node_modules/safe-stable-stringify/readme.md +170 -0
  207. package/node_modules/safe-stable-stringify/tsconfig.json +22 -0
  208. package/node_modules/winston/LICENSE +18 -18
  209. package/node_modules/winston/README.md +1231 -1230
  210. package/node_modules/winston/dist/winston/common.js +10 -10
  211. package/node_modules/winston/dist/winston/config/index.js +17 -17
  212. package/node_modules/winston/dist/winston/container.js +46 -46
  213. package/node_modules/winston/dist/winston/create-logger.js +28 -24
  214. package/node_modules/winston/dist/winston/exception-handler.js +49 -49
  215. package/node_modules/winston/dist/winston/exception-stream.js +27 -27
  216. package/node_modules/winston/dist/winston/logger.js +152 -138
  217. package/node_modules/winston/dist/winston/profiler.js +22 -22
  218. package/node_modules/winston/dist/winston/rejection-handler.js +54 -54
  219. package/node_modules/winston/dist/winston/tail-file.js +14 -14
  220. package/node_modules/winston/dist/winston/transports/console.js +31 -31
  221. package/node_modules/winston/dist/winston/transports/file.js +101 -101
  222. package/node_modules/winston/dist/winston/transports/http.js +119 -41
  223. package/node_modules/winston/dist/winston/transports/index.js +17 -17
  224. package/node_modules/winston/dist/winston/transports/stream.js +24 -24
  225. package/node_modules/winston/dist/winston.js +91 -97
  226. package/node_modules/winston/index.d.ts +213 -193
  227. package/node_modules/winston/lib/winston/common.js +61 -61
  228. package/node_modules/winston/lib/winston/config/index.d.ts +99 -98
  229. package/node_modules/winston/lib/winston/config/index.js +35 -35
  230. package/node_modules/winston/lib/winston/container.js +114 -114
  231. package/node_modules/winston/lib/winston/create-logger.js +104 -104
  232. package/node_modules/winston/lib/winston/exception-handler.js +245 -245
  233. package/node_modules/winston/lib/winston/exception-stream.js +54 -54
  234. package/node_modules/winston/lib/winston/logger.js +676 -667
  235. package/node_modules/winston/lib/winston/profiler.js +51 -51
  236. package/node_modules/winston/lib/winston/rejection-handler.js +251 -251
  237. package/node_modules/winston/lib/winston/tail-file.js +124 -124
  238. package/node_modules/winston/lib/winston/transports/console.js +117 -117
  239. package/node_modules/winston/lib/winston/transports/file.js +695 -695
  240. package/node_modules/winston/lib/winston/transports/http.js +267 -202
  241. package/node_modules/winston/lib/winston/transports/index.d.ts +103 -100
  242. package/node_modules/winston/lib/winston/transports/index.js +56 -56
  243. package/node_modules/winston/lib/winston/transports/stream.js +63 -63
  244. package/node_modules/winston/lib/winston.js +176 -182
  245. package/node_modules/winston/node_modules/winston-transport/.babelrc +3 -0
  246. package/node_modules/winston/node_modules/winston-transport/.eslintrc +7 -0
  247. package/node_modules/winston/node_modules/winston-transport/.gitattributes +1 -0
  248. package/node_modules/winston/node_modules/winston-transport/.nyc_output/c3d7ddb9-cc26-466b-a4f6-993ad69e86f6.json +1 -0
  249. package/node_modules/winston/node_modules/winston-transport/.nyc_output/processinfo/c3d7ddb9-cc26-466b-a4f6-993ad69e86f6.json +1 -0
  250. package/node_modules/winston/node_modules/winston-transport/.nyc_output/processinfo/index.json +1 -0
  251. package/node_modules/winston/node_modules/winston-transport/CHANGELOG.md +126 -0
  252. package/node_modules/winston/node_modules/winston-transport/LICENSE +22 -0
  253. package/node_modules/winston/node_modules/winston-transport/README.md +50 -0
  254. package/node_modules/winston/node_modules/winston-transport/dist/index.js +215 -0
  255. package/node_modules/winston/node_modules/winston-transport/dist/legacy.js +116 -0
  256. package/node_modules/winston/node_modules/winston-transport/index.d.ts +39 -0
  257. package/node_modules/winston/node_modules/winston-transport/index.js +215 -0
  258. package/node_modules/winston/node_modules/winston-transport/legacy.js +119 -0
  259. package/node_modules/winston/node_modules/winston-transport/package.json +56 -0
  260. package/node_modules/winston/package.json +76 -75
  261. package/package.json +8 -6
  262. package/node_modules/@dabh/diagnostics/example.png +0 -0
  263. package/node_modules/color-string/CHANGELOG.md +0 -18
  264. package/node_modules/colorspace/test.js +0 -14
  265. package/node_modules/fecha/CHANGELOG.md +0 -67
  266. package/node_modules/logform/.travis.yml +0 -17
  267. package/node_modules/winston/CHANGELOG.md +0 -560
@@ -1,1230 +1,1231 @@
1
- # winston
2
-
3
- A logger for just about everything.
4
-
5
- [![Version npm](https://img.shields.io/npm/v/winston.svg?style=flat-square)](https://www.npmjs.com/package/winston)[![npm Downloads](https://img.shields.io/npm/dm/winston.svg?style=flat-square)](https://npmcharts.com/compare/winston?minimal=true)[![Build Status](https://img.shields.io/travis/winstonjs/winston/master.svg?style=flat-square)](https://travis-ci.org/winstonjs/winston)[![Dependencies](https://img.shields.io/david/winstonjs/winston.svg?style=flat-square)](https://david-dm.org/winstonjs/winston)
6
-
7
- [![NPM](https://nodei.co/npm/winston.png?downloads=true&downloadRank=true)](https://nodei.co/npm/winston/)
8
-
9
- [![Join the chat at https://gitter.im/winstonjs/winston](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/winstonjs/winston?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
10
-
11
- ## winston@3
12
-
13
- See the [Upgrade Guide](UPGRADE-3.0.md) for more information. Bug reports and
14
- PRs welcome!
15
-
16
- ## Looking for `winston@2.x` documentation?
17
-
18
- Please note that the documentation below is for `winston@3`.
19
- [Read the `winston@2.x` documentation].
20
-
21
- ## Motivation
22
-
23
- `winston` is designed to be a simple and universal logging library with
24
- support for multiple transports. A transport is essentially a storage device
25
- for your logs. Each `winston` logger can have multiple transports (see:
26
- [Transports]) configured at different levels (see: [Logging levels]). For
27
- example, one may want error logs to be stored in a persistent remote location
28
- (like a database), but all logs output to the console or a local file.
29
-
30
- `winston` aims to decouple parts of the logging process to make it more
31
- flexible and extensible. Attention is given to supporting flexibility in log
32
- formatting (see: [Formats]) & levels (see: [Using custom logging levels]), and
33
- ensuring those APIs decoupled from the implementation of transport logging
34
- (i.e. how the logs are stored / indexed, see: [Adding Custom Transports]) to
35
- the API that they exposed to the programmer.
36
-
37
- ## Quick Start
38
-
39
- TL;DR? Check out the [quick start example][quick-example] in `./examples/`.
40
- There are a number of other examples in [`./examples/*.js`][examples].
41
- Don't see an example you think should be there? Submit a pull request
42
- to add it!
43
-
44
- ## Usage
45
-
46
- The recommended way to use `winston` is to create your own logger. The
47
- simplest way to do this is using `winston.createLogger`:
48
-
49
- ``` js
50
- const winston = require('winston');
51
-
52
- const logger = winston.createLogger({
53
- level: 'info',
54
- format: winston.format.json(),
55
- defaultMeta: { service: 'user-service' },
56
- transports: [
57
- //
58
- // - Write all logs with level `error` and below to `error.log`
59
- // - Write all logs with level `info` and below to `combined.log`
60
- //
61
- new winston.transports.File({ filename: 'error.log', level: 'error' }),
62
- new winston.transports.File({ filename: 'combined.log' }),
63
- ],
64
- });
65
-
66
- //
67
- // If we're not in production then log to the `console` with the format:
68
- // `${info.level}: ${info.message} JSON.stringify({ ...rest }) `
69
- //
70
- if (process.env.NODE_ENV !== 'production') {
71
- logger.add(new winston.transports.Console({
72
- format: winston.format.simple(),
73
- }));
74
- }
75
- ```
76
-
77
- You may also log directly via the default logger exposed by
78
- `require('winston')`, but this merely intended to be a convenient shared
79
- logger to use throughout your application if you so choose.
80
-
81
- ## Table of contents
82
-
83
- * [Motivation](#motivation)
84
- * [Quick Start](#quick-start)
85
- * [Usage](#usage)
86
- * [Table of Contents](#table-of-contents)
87
- * [Logging](#logging)
88
- * [Creating your logger](#creating-your-own-logger)
89
- * [Streams, `objectMode`, and `info` objects](#streams-objectmode-and-info-objects)
90
- * [Formats]
91
- * [Combining formats](#combining-formats)
92
- * [String interpolation](#string-interpolation)
93
- * [Filtering `info` Objects](#filtering-info-objects)
94
- * [Creating custom formats](#creating-custom-formats)
95
- * [Logging levels]
96
- * [Using logging levels](#using-logging-levels)
97
- * [Using custom logging levels](#using-custom-logging-levels)
98
- * [Transports]
99
- * [Multiple transports of the same type](#multiple-transports-of-the-same-type)
100
- * [Adding Custom Transports](#adding-custom-transports)
101
- * [Common Transport options](#common-transport-options)
102
- * [Exceptions](#exceptions)
103
- * [Handling Uncaught Exceptions with winston](#handling-uncaught-exceptions-with-winston)
104
- * [To Exit or Not to Exit](#to-exit-or-not-to-exit)
105
- * [Rejections](#rejections)
106
- * [Handling Uncaught Promise Rejections with winston](#handling-uncaught-promise-rejections-with-winston)
107
- * [Profiling](#profiling)
108
- * [Streaming Logs](#streaming-logs)
109
- * [Querying Logs](#querying-logs)
110
- * [Further Reading](#further-reading)
111
- * [Using the default logger](#using-the-default-logger)
112
- * [Awaiting logs to be written in `winston`](#awaiting-logs-to-be-written-in-winston)
113
- * [Working with multiple Loggers in `winston`](#working-with-multiple-loggers-in-winston)
114
- * [Installation](#installation)
115
- * [Run Tests](#run-tests)
116
-
117
- ## Logging
118
-
119
- Logging levels in `winston` conform to the severity ordering specified by
120
- [RFC5424]: _severity of all levels is assumed to be numerically **ascending**
121
- from most important to least important._
122
-
123
- ``` js
124
- const levels = {
125
- error: 0,
126
- warn: 1,
127
- info: 2,
128
- http: 3,
129
- verbose: 4,
130
- debug: 5,
131
- silly: 6
132
- };
133
- ```
134
-
135
- ### Creating your own Logger
136
- You get started by creating a logger using `winston.createLogger`:
137
-
138
- ``` js
139
- const logger = winston.createLogger({
140
- transports: [
141
- new winston.transports.Console(),
142
- new winston.transports.File({ filename: 'combined.log' })
143
- ]
144
- });
145
- ```
146
-
147
- A logger accepts the following parameters:
148
-
149
- | Name | Default | Description |
150
- | ------------- | --------------------------- | --------------- |
151
- | `level` | `'info'` | Log only if [`info.level`](#streams-objectmode-and-info-objects) less than or equal to this level |
152
- | `levels` | `winston.config.npm.levels` | Levels (and colors) representing log priorities |
153
- | `format` | `winston.format.json` | Formatting for `info` messages (see: [Formats]) |
154
- | `transports` | `[]` _(No transports)_ | Set of logging targets for `info` messages |
155
- | `exitOnError` | `true` | If false, handled exceptions will not cause `process.exit` |
156
- | `silent` | `false` | If true, all logs are suppressed |
157
-
158
- The levels provided to `createLogger` will be defined as convenience methods
159
- on the `logger` returned.
160
-
161
- ``` js
162
- //
163
- // Logging
164
- //
165
- logger.log({
166
- level: 'info',
167
- message: 'Hello distributed log files!'
168
- });
169
-
170
- logger.info('Hello again distributed logs');
171
- ```
172
-
173
- You can add or remove transports from the `logger` once it has been provided
174
- to you from `winston.createLogger`:
175
-
176
- ``` js
177
- const files = new winston.transports.File({ filename: 'combined.log' });
178
- const console = new winston.transports.Console();
179
-
180
- logger
181
- .clear() // Remove all transports
182
- .add(console) // Add console transport
183
- .add(files) // Add file transport
184
- .remove(console); // Remove console transport
185
- ```
186
-
187
- You can also wholesale reconfigure a `winston.Logger` instance using the
188
- `configure` method:
189
-
190
- ``` js
191
- const logger = winston.createLogger({
192
- level: 'info',
193
- transports: [
194
- new winston.transports.Console(),
195
- new winston.transports.File({ filename: 'combined.log' })
196
- ]
197
- });
198
-
199
- //
200
- // Replaces the previous transports with those in the
201
- // new configuration wholesale.
202
- //
203
- const DailyRotateFile = require('winston-daily-rotate-file');
204
- logger.configure({
205
- level: 'verbose',
206
- transports: [
207
- new DailyRotateFile(opts)
208
- ]
209
- });
210
- ```
211
-
212
- ### Creating child loggers
213
-
214
- You can create child loggers from existing loggers to pass metadata overrides:
215
-
216
- ``` js
217
- const logger = winston.createLogger({
218
- transports: [
219
- new winston.transports.Console(),
220
- ]
221
- });
222
-
223
- const childLogger = logger.child({ requestId: '451' });
224
- ```
225
-
226
- ### Streams, `objectMode`, and `info` objects
227
-
228
- In `winston`, both `Logger` and `Transport` instances are treated as
229
- [`objectMode`](https://nodejs.org/api/stream.html#stream_object_mode)
230
- streams that accept an `info` object.
231
-
232
- The `info` parameter provided to a given format represents a single log
233
- message. The object itself is mutable. Every `info` must have at least the
234
- `level` and `message` properties:
235
-
236
- ``` js
237
- const info = {
238
- level: 'info', // Level of the logging message
239
- message: 'Hey! Log something?' // Descriptive message being logged.
240
- };
241
- ```
242
-
243
- Properties **besides level and message** are considered as "`meta`". i.e.:
244
-
245
- ``` js
246
- const { level, message, ...meta } = info;
247
- ```
248
-
249
- Several of the formats in `logform` itself add additional properties:
250
-
251
- | Property | Format added by | Description |
252
- | ----------- | --------------- | ----------- |
253
- | `splat` | `splat()` | String interpolation splat for `%d %s`-style messages. |
254
- | `timestamp` | `timestamp()` | timestamp the message was received. |
255
- | `label` | `label()` | Custom label associated with each message. |
256
- | `ms` | `ms()` | Number of milliseconds since the previous log message. |
257
-
258
- As a consumer you may add whatever properties you wish – _internal state is
259
- maintained by `Symbol` properties:_
260
-
261
- - `Symbol.for('level')` _**(READ-ONLY)**:_ equal to `level` property.
262
- **Is treated as immutable by all code.**
263
- - `Symbol.for('message'):` complete string message set by "finalizing formats":
264
- - `json`
265
- - `logstash`
266
- - `printf`
267
- - `prettyPrint`
268
- - `simple`
269
- - `Symbol.for('splat')`: additional string interpolation arguments. _Used
270
- exclusively by `splat()` format._
271
-
272
- These Symbols are stored in another package: `triple-beam` so that all
273
- consumers of `logform` can have the same Symbol reference. i.e.:
274
-
275
- ``` js
276
- const { LEVEL, MESSAGE, SPLAT } = require('triple-beam');
277
-
278
- console.log(LEVEL === Symbol.for('level'));
279
- // true
280
-
281
- console.log(MESSAGE === Symbol.for('message'));
282
- // true
283
-
284
- console.log(SPLAT === Symbol.for('splat'));
285
- // true
286
- ```
287
-
288
- > **NOTE:** any `{ message }` property in a `meta` object provided will
289
- > automatically be concatenated to any `msg` already provided: For
290
- > example the below will concatenate 'world' onto 'hello':
291
- >
292
- > ``` js
293
- > logger.log('error', 'hello', { message: 'world' });
294
- > logger.info('hello', { message: 'world' });
295
- > ```
296
-
297
- ## Formats
298
-
299
- Formats in `winston` can be accessed from `winston.format`. They are
300
- implemented in [`logform`](https://github.com/winstonjs/logform), a separate
301
- module from `winston`. This allows flexibility when writing your own transports
302
- in case you wish to include a default format with your transport.
303
-
304
- In modern versions of `node` template strings are very performant and are the
305
- recommended way for doing most end-user formatting. If you want to bespoke
306
- format your logs, `winston.format.printf` is for you:
307
-
308
- ``` js
309
- const { createLogger, format, transports } = require('winston');
310
- const { combine, timestamp, label, printf } = format;
311
-
312
- const myFormat = printf(({ level, message, label, timestamp }) => {
313
- return `${timestamp} [${label}] ${level}: ${message}`;
314
- });
315
-
316
- const logger = createLogger({
317
- format: combine(
318
- label({ label: 'right meow!' }),
319
- timestamp(),
320
- myFormat
321
- ),
322
- transports: [new transports.Console()]
323
- });
324
- ```
325
-
326
- To see what built-in formats are available and learn more about creating your
327
- own custom logging formats, see [`logform`][logform].
328
-
329
- ### Combining formats
330
-
331
- Any number of formats may be combined into a single format using
332
- `format.combine`. Since `format.combine` takes no `opts`, as a convenience it
333
- returns pre-created instance of the combined format.
334
-
335
- ``` js
336
- const { createLogger, format, transports } = require('winston');
337
- const { combine, timestamp, label, prettyPrint } = format;
338
-
339
- const logger = createLogger({
340
- format: combine(
341
- label({ label: 'right meow!' }),
342
- timestamp(),
343
- prettyPrint()
344
- ),
345
- transports: [new transports.Console()]
346
- })
347
-
348
- logger.log({
349
- level: 'info',
350
- message: 'What time is the testing at?'
351
- });
352
- // Outputs:
353
- // { level: 'info',
354
- // message: 'What time is the testing at?',
355
- // label: 'right meow!',
356
- // timestamp: '2017-09-30T03:57:26.875Z' }
357
- ```
358
-
359
- ### String interpolation
360
-
361
- The `log` method provides the string interpolation using [util.format]. **It
362
- must be enabled using `format.splat()`.**
363
-
364
- Below is an example that defines a format with string interpolation of
365
- messages using `format.splat` and then serializes the entire `info` message
366
- using `format.simple`.
367
-
368
- ``` js
369
- const { createLogger, format, transports } = require('winston');
370
- const logger = createLogger({
371
- format: format.combine(
372
- format.splat(),
373
- format.simple()
374
- ),
375
- transports: [new transports.Console()]
376
- });
377
-
378
- // info: test message my string {}
379
- logger.log('info', 'test message %s', 'my string');
380
-
381
- // info: test message 123 {}
382
- logger.log('info', 'test message %d', 123);
383
-
384
- // info: test message first second {number: 123}
385
- logger.log('info', 'test message %s, %s', 'first', 'second', { number: 123 });
386
- ```
387
-
388
- ### Filtering `info` Objects
389
-
390
- If you wish to filter out a given `info` Object completely when logging then
391
- simply return a falsey value.
392
-
393
- ``` js
394
- const { createLogger, format, transports } = require('winston');
395
-
396
- // Ignore log messages if they have { private: true }
397
- const ignorePrivate = format((info, opts) => {
398
- if (info.private) { return false; }
399
- return info;
400
- });
401
-
402
- const logger = createLogger({
403
- format: format.combine(
404
- ignorePrivate(),
405
- format.json()
406
- ),
407
- transports: [new transports.Console()]
408
- });
409
-
410
- // Outputs: {"level":"error","message":"Public error to share"}
411
- logger.log({
412
- level: 'error',
413
- message: 'Public error to share'
414
- });
415
-
416
- // Messages with { private: true } will not be written when logged.
417
- logger.log({
418
- private: true,
419
- level: 'error',
420
- message: 'This is super secret - hide it.'
421
- });
422
- ```
423
-
424
- Use of `format.combine` will respect any falsey values return and stop
425
- evaluation of later formats in the series. For example:
426
-
427
- ``` js
428
- const { format } = require('winston');
429
- const { combine, timestamp, label } = format;
430
-
431
- const willNeverThrow = format.combine(
432
- format(info => { return false })(), // Ignores everything
433
- format(info => { throw new Error('Never reached') })()
434
- );
435
- ```
436
-
437
- ### Creating custom formats
438
-
439
- Formats are prototypal objects (i.e. class instances) that define a single
440
- method: `transform(info, opts)` and return the mutated `info`:
441
-
442
- - `info`: an object representing the log message.
443
- - `opts`: setting specific to the current instance of the format.
444
-
445
- They are expected to return one of two things:
446
-
447
- - **An `info` Object** representing the modified `info` argument. Object
448
- references need not be preserved if immutability is preferred. All current
449
- built-in formats consider `info` mutable, but [immutablejs] is being
450
- considered for future releases.
451
- - **A falsey value** indicating that the `info` argument should be ignored by the
452
- caller. (See: [Filtering `info` Objects](#filtering-info-objects)) below.
453
-
454
- `winston.format` is designed to be as simple as possible. To define a new
455
- format simple pass it a `transform(info, opts)` function to get a new
456
- `Format`.
457
-
458
- The named `Format` returned can be used to create as many copies of the given
459
- `Format` as desired:
460
-
461
- ``` js
462
- const { format } = require('winston');
463
-
464
- const volume = format((info, opts) => {
465
- if (opts.yell) {
466
- info.message = info.message.toUpperCase();
467
- } else if (opts.whisper) {
468
- info.message = info.message.toLowerCase();
469
- }
470
-
471
- return info;
472
- });
473
-
474
- // `volume` is now a function that returns instances of the format.
475
- const scream = volume({ yell: true });
476
- console.dir(scream.transform({
477
- level: 'info',
478
- message: `sorry for making you YELL in your head!`
479
- }, scream.options));
480
- // {
481
- // level: 'info'
482
- // message: 'SORRY FOR MAKING YOU YELL IN YOUR HEAD!'
483
- // }
484
-
485
- // `volume` can be used multiple times to create different formats.
486
- const whisper = volume({ whisper: true });
487
- console.dir(whisper.transform({
488
- level: 'info',
489
- message: `WHY ARE THEY MAKING US YELL SO MUCH!`
490
- }, whisper.options));
491
- // {
492
- // level: 'info'
493
- // message: 'why are they making us yell so much!'
494
- // }
495
- ```
496
-
497
- ## Logging Levels
498
-
499
- Logging levels in `winston` conform to the severity ordering specified by
500
- [RFC5424]: _severity of all levels is assumed to be numerically **ascending**
501
- from most important to least important._
502
-
503
- Each `level` is given a specific integer priority. The higher the priority the
504
- more important the message is considered to be, and the lower the
505
- corresponding integer priority. For example, as specified exactly in RFC5424
506
- the `syslog` levels are prioritized from 0 to 7 (highest to lowest).
507
-
508
- ```js
509
- {
510
- emerg: 0,
511
- alert: 1,
512
- crit: 2,
513
- error: 3,
514
- warning: 4,
515
- notice: 5,
516
- info: 6,
517
- debug: 7
518
- }
519
- ```
520
-
521
- Similarly, `npm` logging levels are prioritized from 0 to 6 (highest to
522
- lowest):
523
-
524
- ``` js
525
- {
526
- error: 0,
527
- warn: 1,
528
- info: 2,
529
- http: 3,
530
- verbose: 4,
531
- debug: 5,
532
- silly: 6
533
- }
534
- ```
535
-
536
- If you do not explicitly define the levels that `winston` should use, the
537
- `npm` levels above will be used.
538
-
539
- ### Using Logging Levels
540
-
541
- Setting the level for your logging message can be accomplished in one of two
542
- ways. You can pass a string representing the logging level to the log() method
543
- or use the level specified methods defined on every winston Logger.
544
-
545
- ``` js
546
- //
547
- // Any logger instance
548
- //
549
- logger.log('silly', "127.0.0.1 - there's no place like home");
550
- logger.log('debug', "127.0.0.1 - there's no place like home");
551
- logger.log('verbose', "127.0.0.1 - there's no place like home");
552
- logger.log('info', "127.0.0.1 - there's no place like home");
553
- logger.log('warn', "127.0.0.1 - there's no place like home");
554
- logger.log('error', "127.0.0.1 - there's no place like home");
555
- logger.info("127.0.0.1 - there's no place like home");
556
- logger.warn("127.0.0.1 - there's no place like home");
557
- logger.error("127.0.0.1 - there's no place like home");
558
-
559
- //
560
- // Default logger
561
- //
562
- winston.log('info', "127.0.0.1 - there's no place like home");
563
- winston.info("127.0.0.1 - there's no place like home");
564
- ```
565
-
566
- `winston` allows you to define a `level` property on each transport which
567
- specifies the **maximum** level of messages that a transport should log. For
568
- example, using the `syslog` levels you could log only `error` messages to the
569
- console and everything `info` and below to a file (which includes `error`
570
- messages):
571
-
572
- ``` js
573
- const logger = winston.createLogger({
574
- levels: winston.config.syslog.levels,
575
- transports: [
576
- new winston.transports.Console({ level: 'error' }),
577
- new winston.transports.File({
578
- filename: 'combined.log',
579
- level: 'info'
580
- })
581
- ]
582
- });
583
- ```
584
-
585
- You may also dynamically change the log level of a transport:
586
-
587
- ``` js
588
- const transports = {
589
- console: new winston.transports.Console({ level: 'warn' }),
590
- file: new winston.transports.File({ filename: 'combined.log', level: 'error' })
591
- };
592
-
593
- const logger = winston.createLogger({
594
- transports: [
595
- transports.console,
596
- transports.file
597
- ]
598
- });
599
-
600
- logger.info('Will not be logged in either transport!');
601
- transports.console.level = 'info';
602
- transports.file.level = 'info';
603
- logger.info('Will be logged in both transports!');
604
- ```
605
-
606
- `winston` supports customizable logging levels, defaulting to npm style
607
- logging levels. Levels must be specified at the time of creating your logger.
608
-
609
- ### Using Custom Logging Levels
610
-
611
- In addition to the predefined `npm`, `syslog`, and `cli` levels available in
612
- `winston`, you can also choose to define your own:
613
-
614
- ``` js
615
- const myCustomLevels = {
616
- levels: {
617
- foo: 0,
618
- bar: 1,
619
- baz: 2,
620
- foobar: 3
621
- },
622
- colors: {
623
- foo: 'blue',
624
- bar: 'green',
625
- baz: 'yellow',
626
- foobar: 'red'
627
- }
628
- };
629
-
630
- const customLevelLogger = winston.createLogger({
631
- levels: myCustomLevels.levels
632
- });
633
-
634
- customLevelLogger.foobar('some foobar level-ed message');
635
- ```
636
-
637
- Although there is slight repetition in this data structure, it enables simple
638
- encapsulation if you do not want to have colors. If you do wish to have
639
- colors, in addition to passing the levels to the Logger itself, you must make
640
- winston aware of them:
641
-
642
- ``` js
643
- winston.addColors(myCustomLevels.colors);
644
- ```
645
-
646
- This enables loggers using the `colorize` formatter to appropriately color and style
647
- the output of custom levels.
648
-
649
- Additionally, you can also change background color and font style.
650
- For example,
651
- ``` js
652
- baz: 'italic yellow',
653
- foobar: 'bold red cyanBG'
654
- ```
655
-
656
- Possible options are below.
657
-
658
- * Font styles: `bold`, `dim`, `italic`, `underline`, `inverse`, `hidden`,
659
- `strikethrough`.
660
-
661
- * Font foreground colors: `black`, `red`, `green`, `yellow`, `blue`, `magenta`,
662
- `cyan`, `white`, `gray`, `grey`.
663
-
664
- * Background colors: `blackBG`, `redBG`, `greenBG`, `yellowBG`, `blueBG`
665
- `magentaBG`, `cyanBG`, `whiteBG`
666
-
667
- ### Colorizing Standard logging levels
668
-
669
- To colorize the standard logging level add
670
- ```js
671
- winston.format.combine(
672
- winston.format.colorize(),
673
- winston.format.json()
674
- );
675
- ```
676
- where `winston.format.json()` is whatever other formatter you want to use. The `colorize` formatter must come before any formatters adding text you wish to color.
677
-
678
- ## Transports
679
-
680
- There are several [core transports] included in `winston`, which leverage the
681
- built-in networking and file I/O offered by Node.js core. In addition, there
682
- are [additional transports] written by members of the community.
683
-
684
- ## Multiple transports of the same type
685
-
686
- It is possible to use multiple transports of the same type e.g.
687
- `winston.transports.File` when you construct the transport.
688
-
689
- ``` js
690
- const logger = winston.createLogger({
691
- transports: [
692
- new winston.transports.File({
693
- filename: 'combined.log',
694
- level: 'info'
695
- }),
696
- new winston.transports.File({
697
- filename: 'errors.log',
698
- level: 'error'
699
- })
700
- ]
701
- });
702
- ```
703
-
704
- If you later want to remove one of these transports you can do so by using the
705
- transport itself. e.g.:
706
-
707
- ``` js
708
- const combinedLogs = logger.transports.find(transport => {
709
- return transport.filename === 'combined.log'
710
- });
711
-
712
- logger.remove(combinedLogs);
713
- ```
714
-
715
- ## Adding Custom Transports
716
-
717
- Adding a custom transport is easy. All you need to do is accept any options
718
- you need, implement a log() method, and consume it with `winston`.
719
-
720
- ``` js
721
- const Transport = require('winston-transport');
722
- const util = require('util');
723
-
724
- //
725
- // Inherit from `winston-transport` so you can take advantage
726
- // of the base functionality and `.exceptions.handle()`.
727
- //
728
- module.exports = class YourCustomTransport extends Transport {
729
- constructor(opts) {
730
- super(opts);
731
- //
732
- // Consume any custom options here. e.g.:
733
- // - Connection information for databases
734
- // - Authentication information for APIs (e.g. loggly, papertrail,
735
- // logentries, etc.).
736
- //
737
- }
738
-
739
- log(info, callback) {
740
- setImmediate(() => {
741
- this.emit('logged', info);
742
- });
743
-
744
- // Perform the writing to the remote service
745
- callback();
746
- }
747
- };
748
- ```
749
-
750
- ## Common Transport options
751
-
752
- As every transport inherits from [winston-transport], it's possible to set
753
- a custom format and a custom log level on each transport separately:
754
-
755
- ``` js
756
- const logger = winston.createLogger({
757
- transports: [
758
- new winston.transports.File({
759
- filename: 'error.log',
760
- level: 'error',
761
- format: winston.format.json()
762
- }),
763
- new transports.Http({
764
- level: 'warn',
765
- format: winston.format.json()
766
- }),
767
- new transports.Console({
768
- level: 'info',
769
- format: winston.format.combine(
770
- winston.format.colorize(),
771
- winston.format.simple()
772
- )
773
- })
774
- ]
775
- });
776
- ```
777
-
778
- ## Exceptions
779
-
780
- ### Handling Uncaught Exceptions with winston
781
-
782
- With `winston`, it is possible to catch and log `uncaughtException` events
783
- from your process. With your own logger instance you can enable this behavior
784
- when it's created or later on in your applications lifecycle:
785
-
786
- ``` js
787
- const { createLogger, transports } = require('winston');
788
-
789
- // Enable exception handling when you create your logger.
790
- const logger = createLogger({
791
- transports: [
792
- new transports.File({ filename: 'combined.log' })
793
- ],
794
- exceptionHandlers: [
795
- new transports.File({ filename: 'exceptions.log' })
796
- ]
797
- });
798
-
799
- // Or enable it later on by adding a transport or using `.exceptions.handle`
800
- const logger = createLogger({
801
- transports: [
802
- new transports.File({ filename: 'combined.log' })
803
- ]
804
- });
805
-
806
- // Call exceptions.handle with a transport to handle exceptions
807
- logger.exceptions.handle(
808
- new transports.File({ filename: 'exceptions.log' })
809
- );
810
- ```
811
-
812
- If you want to use this feature with the default logger, simply call
813
- `.exceptions.handle()` with a transport instance.
814
-
815
- ``` js
816
- //
817
- // You can add a separate exception logger by passing it to `.exceptions.handle`
818
- //
819
- winston.exceptions.handle(
820
- new winston.transports.File({ filename: 'path/to/exceptions.log' })
821
- );
822
-
823
- //
824
- // Alternatively you can set `handleExceptions` to true when adding transports
825
- // to winston.
826
- //
827
- winston.add(new winston.transports.File({
828
- filename: 'path/to/combined.log',
829
- handleExceptions: true
830
- }));
831
- ```
832
-
833
- ### To Exit or Not to Exit
834
-
835
- By default, winston will exit after logging an uncaughtException. If this is
836
- not the behavior you want, set `exitOnError = false`
837
-
838
- ``` js
839
- const logger = winston.createLogger({ exitOnError: false });
840
-
841
- //
842
- // or, like this:
843
- //
844
- logger.exitOnError = false;
845
- ```
846
-
847
- When working with custom logger instances, you can pass in separate transports
848
- to the `exceptionHandlers` property or set `handleExceptions` on any
849
- transport.
850
-
851
- ##### Example 1
852
-
853
- ``` js
854
- const logger = winston.createLogger({
855
- transports: [
856
- new winston.transports.File({ filename: 'path/to/combined.log' })
857
- ],
858
- exceptionHandlers: [
859
- new winston.transports.File({ filename: 'path/to/exceptions.log' })
860
- ]
861
- });
862
- ```
863
-
864
- ##### Example 2
865
-
866
- ``` js
867
- const logger = winston.createLogger({
868
- transports: [
869
- new winston.transports.Console({
870
- handleExceptions: true
871
- })
872
- ],
873
- exitOnError: false
874
- });
875
- ```
876
-
877
- The `exitOnError` option can also be a function to prevent exit on only
878
- certain types of errors:
879
-
880
- ``` js
881
- function ignoreEpipe(err) {
882
- return err.code !== 'EPIPE';
883
- }
884
-
885
- const logger = winston.createLogger({ exitOnError: ignoreEpipe });
886
-
887
- //
888
- // or, like this:
889
- //
890
- logger.exitOnError = ignoreEpipe;
891
- ```
892
-
893
- ## Rejections
894
-
895
- ### Handling Uncaught Promise Rejections with winston
896
-
897
- With `winston`, it is possible to catch and log `uncaughtRejection` events
898
- from your process. With your own logger instance you can enable this behavior
899
- when it's created or later on in your applications lifecycle:
900
-
901
- ``` js
902
- const { createLogger, transports } = require('winston');
903
-
904
- // Enable rejection handling when you create your logger.
905
- const logger = createLogger({
906
- transports: [
907
- new transports.File({ filename: 'combined.log' })
908
- ],
909
- rejectionHandlers: [
910
- new transports.File({ filename: 'rejections.log' })
911
- ]
912
- });
913
-
914
- // Or enable it later on by adding a transport or using `.rejections.handle`
915
- const logger = createLogger({
916
- transports: [
917
- new transports.File({ filename: 'combined.log' })
918
- ]
919
- });
920
-
921
- // Call rejections.handle with a transport to handle rejections
922
- logger.rejections.handle(
923
- new transports.File({ filename: 'rejections.log' })
924
- );
925
- ```
926
-
927
- If you want to use this feature with the default logger, simply call
928
- `.rejections.handle()` with a transport instance.
929
-
930
- ``` js
931
- //
932
- // You can add a separate rejection logger by passing it to `.rejections.handle`
933
- //
934
- winston.rejections.handle(
935
- new winston.transports.File({ filename: 'path/to/rejections.log' })
936
- );
937
-
938
- //
939
- // Alternatively you can set `handleRejections` to true when adding transports
940
- // to winston.
941
- //
942
- winston.add(new winston.transports.File({
943
- filename: 'path/to/combined.log',
944
- handleRejections: true
945
- }));
946
- ```
947
-
948
- ## Profiling
949
-
950
- In addition to logging messages and metadata, `winston` also has a simple
951
- profiling mechanism implemented for any logger:
952
-
953
- ``` js
954
- //
955
- // Start profile of 'test'
956
- //
957
- logger.profile('test');
958
-
959
- setTimeout(function () {
960
- //
961
- // Stop profile of 'test'. Logging will now take place:
962
- // '17 Jan 21:00:00 - info: test duration=1000ms'
963
- //
964
- logger.profile('test');
965
- }, 1000);
966
- ```
967
-
968
- Also you can start a timer and keep a reference that you can call `.done()``
969
- on:
970
-
971
- ``` js
972
- // Returns an object corresponding to a specific timing. When done
973
- // is called the timer will finish and log the duration. e.g.:
974
- //
975
- const profiler = logger.startTimer();
976
- setTimeout(function () {
977
- profiler.done({ message: 'Logging message' });
978
- }, 1000);
979
- ```
980
-
981
- All profile messages are set to 'info' level by default, and both message and
982
- metadata are optional. For individual profile messages, you can override the default log level by supplying a metadata object with a `level` property:
983
-
984
- ```js
985
- logger.profile('test', { level: 'debug' });
986
- ```
987
-
988
- ## Querying Logs
989
-
990
- `winston` supports querying of logs with Loggly-like options. [See Loggly
991
- Search API](https://www.loggly.com/docs/api-retrieving-data/). Specifically:
992
- `File`, `Couchdb`, `Redis`, `Loggly`, `Nssocket`, and `Http`.
993
-
994
- ``` js
995
- const options = {
996
- from: new Date() - (24 * 60 * 60 * 1000),
997
- until: new Date(),
998
- limit: 10,
999
- start: 0,
1000
- order: 'desc',
1001
- fields: ['message']
1002
- };
1003
-
1004
- //
1005
- // Find items logged between today and yesterday.
1006
- //
1007
- logger.query(options, function (err, results) {
1008
- if (err) {
1009
- /* TODO: handle me */
1010
- throw err;
1011
- }
1012
-
1013
- console.log(results);
1014
- });
1015
- ```
1016
-
1017
- ## Streaming Logs
1018
- Streaming allows you to stream your logs back from your chosen transport.
1019
-
1020
- ``` js
1021
- //
1022
- // Start at the end.
1023
- //
1024
- winston.stream({ start: -1 }).on('log', function(log) {
1025
- console.log(log);
1026
- });
1027
- ```
1028
-
1029
- ## Further Reading
1030
-
1031
- ### Using the Default Logger
1032
-
1033
- The default logger is accessible through the `winston` module directly. Any
1034
- method that you could call on an instance of a logger is available on the
1035
- default logger:
1036
-
1037
- ``` js
1038
- const winston = require('winston');
1039
-
1040
- winston.log('info', 'Hello distributed log files!');
1041
- winston.info('Hello again distributed logs');
1042
-
1043
- winston.level = 'debug';
1044
- winston.log('debug', 'Now my debug messages are written to console!');
1045
- ```
1046
-
1047
- By default, no transports are set on the default logger. You must
1048
- add or remove transports via the `add()` and `remove()` methods:
1049
-
1050
- ``` js
1051
- const files = new winston.transports.File({ filename: 'combined.log' });
1052
- const console = new winston.transports.Console();
1053
-
1054
- winston.add(console);
1055
- winston.add(files);
1056
- winston.remove(console);
1057
- ```
1058
-
1059
- Or do it with one call to configure():
1060
-
1061
- ``` js
1062
- winston.configure({
1063
- transports: [
1064
- new winston.transports.File({ filename: 'somefile.log' })
1065
- ]
1066
- });
1067
- ```
1068
-
1069
- For more documentation about working with each individual transport supported
1070
- by `winston` see the [`winston` Transports](docs/transports.md) document.
1071
-
1072
- ### Awaiting logs to be written in `winston`
1073
-
1074
- Often it is useful to wait for your logs to be written before exiting the
1075
- process. Each instance of `winston.Logger` is also a [Node.js stream]. A
1076
- `finish` event will be raised when all logs have flushed to all transports
1077
- after the stream has been ended.
1078
-
1079
- ``` js
1080
- const transport = new winston.transports.Console();
1081
- const logger = winston.createLogger({
1082
- transports: [transport]
1083
- });
1084
-
1085
- logger.on('finish', function (info) {
1086
- // All `info` log messages has now been logged
1087
- });
1088
-
1089
- logger.info('CHILL WINSTON!', { seriously: true });
1090
- logger.end();
1091
- ```
1092
-
1093
- It is also worth mentioning that the logger also emits an 'error' event which
1094
- you should handle or suppress if you don't want unhandled exceptions:
1095
-
1096
- ``` js
1097
- //
1098
- // Handle errors
1099
- //
1100
- logger.on('error', function (err) { /* Do Something */ });
1101
- ```
1102
-
1103
- ### Working with multiple Loggers in winston
1104
-
1105
- Often in larger, more complex, applications it is necessary to have multiple
1106
- logger instances with different settings. Each logger is responsible for a
1107
- different feature area (or category). This is exposed in `winston` in two
1108
- ways: through `winston.loggers` and instances of `winston.Container`. In fact,
1109
- `winston.loggers` is just a predefined instance of `winston.Container`:
1110
-
1111
- ``` js
1112
- const winston = require('winston');
1113
- const { format } = winston;
1114
- const { combine, label, json } = format;
1115
-
1116
- //
1117
- // Configure the logger for `category1`
1118
- //
1119
- winston.loggers.add('category1', {
1120
- format: combine(
1121
- label({ label: 'category one' }),
1122
- json()
1123
- ),
1124
- transports: [
1125
- new winston.transports.Console({ level: 'silly' }),
1126
- new winston.transports.File({ filename: 'somefile.log' })
1127
- ]
1128
- });
1129
-
1130
- //
1131
- // Configure the logger for `category2`
1132
- //
1133
- winston.loggers.add('category2', {
1134
- format: combine(
1135
- label({ label: 'category two' }),
1136
- json()
1137
- ),
1138
- transports: [
1139
- new winston.transports.Http({ host: 'localhost', port:8080 })
1140
- ]
1141
- });
1142
- ```
1143
-
1144
- Now that your loggers are setup, you can require winston _in any file in your
1145
- application_ and access these pre-configured loggers:
1146
-
1147
- ``` js
1148
- const winston = require('winston');
1149
-
1150
- //
1151
- // Grab your preconfigured loggers
1152
- //
1153
- const category1 = winston.loggers.get('category1');
1154
- const category2 = winston.loggers.get('category2');
1155
-
1156
- category1.info('logging to file and console transports');
1157
- category2.info('logging to http transport');
1158
- ```
1159
-
1160
- If you prefer to manage the `Container` yourself, you can simply instantiate one:
1161
-
1162
- ``` js
1163
- const winston = require('winston');
1164
- const { format } = winston;
1165
- const { combine, label, json } = format;
1166
-
1167
- const container = new winston.Container();
1168
-
1169
- container.add('category1', {
1170
- format: combine(
1171
- label({ label: 'category one' }),
1172
- json()
1173
- ),
1174
- transports: [
1175
- new winston.transports.Console({ level: 'silly' }),
1176
- new winston.transports.File({ filename: 'somefile.log' })
1177
- ]
1178
- });
1179
-
1180
- const category1 = container.get('category1');
1181
- category1.info('logging to file and console transports');
1182
- ```
1183
-
1184
- ## Installation
1185
-
1186
- ``` bash
1187
- npm install winston
1188
- ```
1189
-
1190
- ``` bash
1191
- yarn add winston
1192
- ```
1193
-
1194
- ## Run Tests
1195
-
1196
- All of the winston tests are written with [`mocha`][mocha], [`nyc`][nyc], and
1197
- [`assume`][assume]. They can be run with `npm`.
1198
-
1199
- ``` bash
1200
- npm test
1201
- ```
1202
-
1203
- #### Author: [Charlie Robbins]
1204
- #### Contributors: [Jarrett Cruger], [David Hyde], [Chris Alderson]
1205
-
1206
- [Transports]: #transports
1207
- [Logging levels]: #logging-levels
1208
- [Formats]: #formats
1209
- [Using custom logging levels]: #using-custom-logging-levels
1210
- [Adding Custom Transports]: #adding-custom-transports
1211
- [core transports]: docs/transports.md#winston-core
1212
- [additional transports]: docs/transports.md#additional-transports
1213
-
1214
- [RFC5424]: https://tools.ietf.org/html/rfc5424
1215
- [util.format]: https://nodejs.org/dist/latest/docs/api/util.html#util_util_format_format_args
1216
- [mocha]: https://mochajs.org
1217
- [nyc]: https://github.com/istanbuljs/nyc
1218
- [assume]: https://github.com/bigpipe/assume
1219
- [logform]: https://github.com/winstonjs/logform#readme
1220
- [winston-transport]: https://github.com/winstonjs/winston-transport
1221
-
1222
- [Read the `winston@2.x` documentation]: https://github.com/winstonjs/winston/tree/2.x
1223
-
1224
- [quick-example]: https://github.com/winstonjs/winston/blob/master/examples/quick-start.js
1225
- [examples]: https://github.com/winstonjs/winston/tree/master/examples
1226
-
1227
- [Charlie Robbins]: http://github.com/indexzero
1228
- [Jarrett Cruger]: https://github.com/jcrugzz
1229
- [David Hyde]: https://github.com/dabh
1230
- [Chris Alderson]: https://github.com/chrisalderson
1
+ # winston
2
+
3
+ A logger for just about everything.
4
+
5
+ [![Version npm](https://img.shields.io/npm/v/winston.svg?style=flat-square)](https://www.npmjs.com/package/winston)
6
+ [![npm Downloads](https://img.shields.io/npm/dm/winston.svg?style=flat-square)](https://npmcharts.com/compare/winston?minimal=true)
7
+ [![build status](https://github.com/winstonjs/winston/actions/workflows/ci.yml/badge.svg)](https://github.com/winstonjs/winston/actions/workflows/ci.yml)
8
+ [![coverage status](https://coveralls.io/repos/github/winstonjs/winston/badge.svg?branch=master)](https://coveralls.io/github/winstonjs/winston?branch=master)
9
+
10
+ [![NPM](https://nodei.co/npm/winston.png?downloads=true&downloadRank=true)](https://nodei.co/npm/winston/)
11
+
12
+ ## winston@3
13
+
14
+ See the [Upgrade Guide](UPGRADE-3.0.md) for more information. Bug reports and
15
+ PRs welcome!
16
+
17
+ ## Looking for `winston@2.x` documentation?
18
+
19
+ Please note that the documentation below is for `winston@3`.
20
+ [Read the `winston@2.x` documentation].
21
+
22
+ ## Motivation
23
+
24
+ `winston` is designed to be a simple and universal logging library with
25
+ support for multiple transports. A transport is essentially a storage device
26
+ for your logs. Each `winston` logger can have multiple transports (see:
27
+ [Transports]) configured at different levels (see: [Logging levels]). For
28
+ example, one may want error logs to be stored in a persistent remote location
29
+ (like a database), but all logs output to the console or a local file.
30
+
31
+ `winston` aims to decouple parts of the logging process to make it more
32
+ flexible and extensible. Attention is given to supporting flexibility in log
33
+ formatting (see: [Formats]) & levels (see: [Using custom logging levels]), and
34
+ ensuring those APIs decoupled from the implementation of transport logging
35
+ (i.e. how the logs are stored / indexed, see: [Adding Custom Transports]) to
36
+ the API that they exposed to the programmer.
37
+
38
+ ## Quick Start
39
+
40
+ TL;DR? Check out the [quick start example][quick-example] in `./examples/`.
41
+ There are a number of other examples in [`./examples/*.js`][examples].
42
+ Don't see an example you think should be there? Submit a pull request
43
+ to add it!
44
+
45
+ ## Usage
46
+
47
+ The recommended way to use `winston` is to create your own logger. The
48
+ simplest way to do this is using `winston.createLogger`:
49
+
50
+ ``` js
51
+ const winston = require('winston');
52
+
53
+ const logger = winston.createLogger({
54
+ level: 'info',
55
+ format: winston.format.json(),
56
+ defaultMeta: { service: 'user-service' },
57
+ transports: [
58
+ //
59
+ // - Write all logs with importance level of `error` or less to `error.log`
60
+ // - Write all logs with importance level of `info` or less to `combined.log`
61
+ //
62
+ new winston.transports.File({ filename: 'error.log', level: 'error' }),
63
+ new winston.transports.File({ filename: 'combined.log' }),
64
+ ],
65
+ });
66
+
67
+ //
68
+ // If we're not in production then log to the `console` with the format:
69
+ // `${info.level}: ${info.message} JSON.stringify({ ...rest }) `
70
+ //
71
+ if (process.env.NODE_ENV !== 'production') {
72
+ logger.add(new winston.transports.Console({
73
+ format: winston.format.simple(),
74
+ }));
75
+ }
76
+ ```
77
+
78
+ You may also log directly via the default logger exposed by
79
+ `require('winston')`, but this merely intended to be a convenient shared
80
+ logger to use throughout your application if you so choose.
81
+
82
+ ## Table of contents
83
+
84
+ * [Motivation](#motivation)
85
+ * [Quick Start](#quick-start)
86
+ * [Usage](#usage)
87
+ * [Table of Contents](#table-of-contents)
88
+ * [Logging](#logging)
89
+ * [Creating your logger](#creating-your-own-logger)
90
+ * [Streams, `objectMode`, and `info` objects](#streams-objectmode-and-info-objects)
91
+ * [Formats]
92
+ * [Combining formats](#combining-formats)
93
+ * [String interpolation](#string-interpolation)
94
+ * [Filtering `info` Objects](#filtering-info-objects)
95
+ * [Creating custom formats](#creating-custom-formats)
96
+ * [Logging levels]
97
+ * [Using logging levels](#using-logging-levels)
98
+ * [Using custom logging levels](#using-custom-logging-levels)
99
+ * [Transports]
100
+ * [Multiple transports of the same type](#multiple-transports-of-the-same-type)
101
+ * [Adding Custom Transports](#adding-custom-transports)
102
+ * [Common Transport options](#common-transport-options)
103
+ * [Exceptions](#exceptions)
104
+ * [Handling Uncaught Exceptions with winston](#handling-uncaught-exceptions-with-winston)
105
+ * [To Exit or Not to Exit](#to-exit-or-not-to-exit)
106
+ * [Rejections](#rejections)
107
+ * [Handling Uncaught Promise Rejections with winston](#handling-uncaught-promise-rejections-with-winston)
108
+ * [Profiling](#profiling)
109
+ * [Streaming Logs](#streaming-logs)
110
+ * [Querying Logs](#querying-logs)
111
+ * [Further Reading](#further-reading)
112
+ * [Using the default logger](#using-the-default-logger)
113
+ * [Awaiting logs to be written in `winston`](#awaiting-logs-to-be-written-in-winston)
114
+ * [Working with multiple Loggers in `winston`](#working-with-multiple-loggers-in-winston)
115
+ * [Installation](#installation)
116
+ * [Run Tests](#run-tests)
117
+
118
+ ## Logging
119
+
120
+ Logging levels in `winston` conform to the severity ordering specified by
121
+ [RFC5424]: _severity of all levels is assumed to be numerically **ascending**
122
+ from most important to least important._
123
+
124
+ ``` js
125
+ const levels = {
126
+ error: 0,
127
+ warn: 1,
128
+ info: 2,
129
+ http: 3,
130
+ verbose: 4,
131
+ debug: 5,
132
+ silly: 6
133
+ };
134
+ ```
135
+
136
+ ### Creating your own Logger
137
+ You get started by creating a logger using `winston.createLogger`:
138
+
139
+ ``` js
140
+ const logger = winston.createLogger({
141
+ transports: [
142
+ new winston.transports.Console(),
143
+ new winston.transports.File({ filename: 'combined.log' })
144
+ ]
145
+ });
146
+ ```
147
+
148
+ A logger accepts the following parameters:
149
+
150
+ | Name | Default | Description |
151
+ | ------------- | --------------------------- | --------------- |
152
+ | `level` | `'info'` | Log only if [`info.level`](#streams-objectmode-and-info-objects) less than or equal to this level |
153
+ | `levels` | `winston.config.npm.levels` | Levels (and colors) representing log priorities |
154
+ | `format` | `winston.format.json` | Formatting for `info` messages (see: [Formats]) |
155
+ | `transports` | `[]` _(No transports)_ | Set of logging targets for `info` messages |
156
+ | `exitOnError` | `true` | If false, handled exceptions will not cause `process.exit` |
157
+ | `silent` | `false` | If true, all logs are suppressed |
158
+
159
+ The levels provided to `createLogger` will be defined as convenience methods
160
+ on the `logger` returned.
161
+
162
+ ``` js
163
+ //
164
+ // Logging
165
+ //
166
+ logger.log({
167
+ level: 'info',
168
+ message: 'Hello distributed log files!'
169
+ });
170
+
171
+ logger.info('Hello again distributed logs');
172
+ ```
173
+
174
+ You can add or remove transports from the `logger` once it has been provided
175
+ to you from `winston.createLogger`:
176
+
177
+ ``` js
178
+ const files = new winston.transports.File({ filename: 'combined.log' });
179
+ const console = new winston.transports.Console();
180
+
181
+ logger
182
+ .clear() // Remove all transports
183
+ .add(console) // Add console transport
184
+ .add(files) // Add file transport
185
+ .remove(console); // Remove console transport
186
+ ```
187
+
188
+ You can also wholesale reconfigure a `winston.Logger` instance using the
189
+ `configure` method:
190
+
191
+ ``` js
192
+ const logger = winston.createLogger({
193
+ level: 'info',
194
+ transports: [
195
+ new winston.transports.Console(),
196
+ new winston.transports.File({ filename: 'combined.log' })
197
+ ]
198
+ });
199
+
200
+ //
201
+ // Replaces the previous transports with those in the
202
+ // new configuration wholesale.
203
+ //
204
+ const DailyRotateFile = require('winston-daily-rotate-file');
205
+ logger.configure({
206
+ level: 'verbose',
207
+ transports: [
208
+ new DailyRotateFile(opts)
209
+ ]
210
+ });
211
+ ```
212
+
213
+ ### Creating child loggers
214
+
215
+ You can create child loggers from existing loggers to pass metadata overrides:
216
+
217
+ ``` js
218
+ const logger = winston.createLogger({
219
+ transports: [
220
+ new winston.transports.Console(),
221
+ ]
222
+ });
223
+
224
+ const childLogger = logger.child({ requestId: '451' });
225
+ ```
226
+
227
+ ### Streams, `objectMode`, and `info` objects
228
+
229
+ In `winston`, both `Logger` and `Transport` instances are treated as
230
+ [`objectMode`](https://nodejs.org/api/stream.html#stream_object_mode)
231
+ streams that accept an `info` object.
232
+
233
+ The `info` parameter provided to a given format represents a single log
234
+ message. The object itself is mutable. Every `info` must have at least the
235
+ `level` and `message` properties:
236
+
237
+ ``` js
238
+ const info = {
239
+ level: 'info', // Level of the logging message
240
+ message: 'Hey! Log something?' // Descriptive message being logged.
241
+ };
242
+ ```
243
+
244
+ Properties **besides level and message** are considered as "`meta`". i.e.:
245
+
246
+ ``` js
247
+ const { level, message, ...meta } = info;
248
+ ```
249
+
250
+ Several of the formats in `logform` itself add additional properties:
251
+
252
+ | Property | Format added by | Description |
253
+ | ----------- | --------------- | ----------- |
254
+ | `splat` | `splat()` | String interpolation splat for `%d %s`-style messages. |
255
+ | `timestamp` | `timestamp()` | timestamp the message was received. |
256
+ | `label` | `label()` | Custom label associated with each message. |
257
+ | `ms` | `ms()` | Number of milliseconds since the previous log message. |
258
+
259
+ As a consumer you may add whatever properties you wish – _internal state is
260
+ maintained by `Symbol` properties:_
261
+
262
+ - `Symbol.for('level')` _**(READ-ONLY)**:_ equal to `level` property.
263
+ **Is treated as immutable by all code.**
264
+ - `Symbol.for('message'):` complete string message set by "finalizing formats":
265
+ - `json`
266
+ - `logstash`
267
+ - `printf`
268
+ - `prettyPrint`
269
+ - `simple`
270
+ - `Symbol.for('splat')`: additional string interpolation arguments. _Used
271
+ exclusively by `splat()` format._
272
+
273
+ These Symbols are stored in another package: `triple-beam` so that all
274
+ consumers of `logform` can have the same Symbol reference. i.e.:
275
+
276
+ ``` js
277
+ const { LEVEL, MESSAGE, SPLAT } = require('triple-beam');
278
+
279
+ console.log(LEVEL === Symbol.for('level'));
280
+ // true
281
+
282
+ console.log(MESSAGE === Symbol.for('message'));
283
+ // true
284
+
285
+ console.log(SPLAT === Symbol.for('splat'));
286
+ // true
287
+ ```
288
+
289
+ > **NOTE:** any `{ message }` property in a `meta` object provided will
290
+ > automatically be concatenated to any `msg` already provided: For
291
+ > example the below will concatenate 'world' onto 'hello':
292
+ >
293
+ > ``` js
294
+ > logger.log('error', 'hello', { message: 'world' });
295
+ > logger.info('hello', { message: 'world' });
296
+ > ```
297
+
298
+ ## Formats
299
+
300
+ Formats in `winston` can be accessed from `winston.format`. They are
301
+ implemented in [`logform`](https://github.com/winstonjs/logform), a separate
302
+ module from `winston`. This allows flexibility when writing your own transports
303
+ in case you wish to include a default format with your transport.
304
+
305
+ In modern versions of `node` template strings are very performant and are the
306
+ recommended way for doing most end-user formatting. If you want to bespoke
307
+ format your logs, `winston.format.printf` is for you:
308
+
309
+ ``` js
310
+ const { createLogger, format, transports } = require('winston');
311
+ const { combine, timestamp, label, printf } = format;
312
+
313
+ const myFormat = printf(({ level, message, label, timestamp }) => {
314
+ return `${timestamp} [${label}] ${level}: ${message}`;
315
+ });
316
+
317
+ const logger = createLogger({
318
+ format: combine(
319
+ label({ label: 'right meow!' }),
320
+ timestamp(),
321
+ myFormat
322
+ ),
323
+ transports: [new transports.Console()]
324
+ });
325
+ ```
326
+
327
+ To see what built-in formats are available and learn more about creating your
328
+ own custom logging formats, see [`logform`][logform].
329
+
330
+ ### Combining formats
331
+
332
+ Any number of formats may be combined into a single format using
333
+ `format.combine`. Since `format.combine` takes no `opts`, as a convenience it
334
+ returns pre-created instance of the combined format.
335
+
336
+ ``` js
337
+ const { createLogger, format, transports } = require('winston');
338
+ const { combine, timestamp, label, prettyPrint } = format;
339
+
340
+ const logger = createLogger({
341
+ format: combine(
342
+ label({ label: 'right meow!' }),
343
+ timestamp(),
344
+ prettyPrint()
345
+ ),
346
+ transports: [new transports.Console()]
347
+ })
348
+
349
+ logger.log({
350
+ level: 'info',
351
+ message: 'What time is the testing at?'
352
+ });
353
+ // Outputs:
354
+ // { level: 'info',
355
+ // message: 'What time is the testing at?',
356
+ // label: 'right meow!',
357
+ // timestamp: '2017-09-30T03:57:26.875Z' }
358
+ ```
359
+
360
+ ### String interpolation
361
+
362
+ The `log` method provides the string interpolation using [util.format]. **It
363
+ must be enabled using `format.splat()`.**
364
+
365
+ Below is an example that defines a format with string interpolation of
366
+ messages using `format.splat` and then serializes the entire `info` message
367
+ using `format.simple`.
368
+
369
+ ``` js
370
+ const { createLogger, format, transports } = require('winston');
371
+ const logger = createLogger({
372
+ format: format.combine(
373
+ format.splat(),
374
+ format.simple()
375
+ ),
376
+ transports: [new transports.Console()]
377
+ });
378
+
379
+ // info: test message my string {}
380
+ logger.log('info', 'test message %s', 'my string');
381
+
382
+ // info: test message 123 {}
383
+ logger.log('info', 'test message %d', 123);
384
+
385
+ // info: test message first second {number: 123}
386
+ logger.log('info', 'test message %s, %s', 'first', 'second', { number: 123 });
387
+ ```
388
+
389
+ ### Filtering `info` Objects
390
+
391
+ If you wish to filter out a given `info` Object completely when logging then
392
+ simply return a falsey value.
393
+
394
+ ``` js
395
+ const { createLogger, format, transports } = require('winston');
396
+
397
+ // Ignore log messages if they have { private: true }
398
+ const ignorePrivate = format((info, opts) => {
399
+ if (info.private) { return false; }
400
+ return info;
401
+ });
402
+
403
+ const logger = createLogger({
404
+ format: format.combine(
405
+ ignorePrivate(),
406
+ format.json()
407
+ ),
408
+ transports: [new transports.Console()]
409
+ });
410
+
411
+ // Outputs: {"level":"error","message":"Public error to share"}
412
+ logger.log({
413
+ level: 'error',
414
+ message: 'Public error to share'
415
+ });
416
+
417
+ // Messages with { private: true } will not be written when logged.
418
+ logger.log({
419
+ private: true,
420
+ level: 'error',
421
+ message: 'This is super secret - hide it.'
422
+ });
423
+ ```
424
+
425
+ Use of `format.combine` will respect any falsey values return and stop
426
+ evaluation of later formats in the series. For example:
427
+
428
+ ``` js
429
+ const { format } = require('winston');
430
+ const { combine, timestamp, label } = format;
431
+
432
+ const willNeverThrow = format.combine(
433
+ format(info => { return false })(), // Ignores everything
434
+ format(info => { throw new Error('Never reached') })()
435
+ );
436
+ ```
437
+
438
+ ### Creating custom formats
439
+
440
+ Formats are prototypal objects (i.e. class instances) that define a single
441
+ method: `transform(info, opts)` and return the mutated `info`:
442
+
443
+ - `info`: an object representing the log message.
444
+ - `opts`: setting specific to the current instance of the format.
445
+
446
+ They are expected to return one of two things:
447
+
448
+ - **An `info` Object** representing the modified `info` argument. Object
449
+ references need not be preserved if immutability is preferred. All current
450
+ built-in formats consider `info` mutable, but [immutablejs] is being
451
+ considered for future releases.
452
+ - **A falsey value** indicating that the `info` argument should be ignored by the
453
+ caller. (See: [Filtering `info` Objects](#filtering-info-objects)) below.
454
+
455
+ `winston.format` is designed to be as simple as possible. To define a new
456
+ format simple pass it a `transform(info, opts)` function to get a new
457
+ `Format`.
458
+
459
+ The named `Format` returned can be used to create as many copies of the given
460
+ `Format` as desired:
461
+
462
+ ``` js
463
+ const { format } = require('winston');
464
+
465
+ const volume = format((info, opts) => {
466
+ if (opts.yell) {
467
+ info.message = info.message.toUpperCase();
468
+ } else if (opts.whisper) {
469
+ info.message = info.message.toLowerCase();
470
+ }
471
+
472
+ return info;
473
+ });
474
+
475
+ // `volume` is now a function that returns instances of the format.
476
+ const scream = volume({ yell: true });
477
+ console.dir(scream.transform({
478
+ level: 'info',
479
+ message: `sorry for making you YELL in your head!`
480
+ }, scream.options));
481
+ // {
482
+ // level: 'info'
483
+ // message: 'SORRY FOR MAKING YOU YELL IN YOUR HEAD!'
484
+ // }
485
+
486
+ // `volume` can be used multiple times to create different formats.
487
+ const whisper = volume({ whisper: true });
488
+ console.dir(whisper.transform({
489
+ level: 'info',
490
+ message: `WHY ARE THEY MAKING US YELL SO MUCH!`
491
+ }, whisper.options));
492
+ // {
493
+ // level: 'info'
494
+ // message: 'why are they making us yell so much!'
495
+ // }
496
+ ```
497
+
498
+ ## Logging Levels
499
+
500
+ Logging levels in `winston` conform to the severity ordering specified by
501
+ [RFC5424]: _severity of all levels is assumed to be numerically **ascending**
502
+ from most important to least important._
503
+
504
+ Each `level` is given a specific integer priority. The higher the priority the
505
+ more important the message is considered to be, and the lower the
506
+ corresponding integer priority. For example, as specified exactly in RFC5424
507
+ the `syslog` levels are prioritized from 0 to 7 (highest to lowest).
508
+
509
+ ```js
510
+ {
511
+ emerg: 0,
512
+ alert: 1,
513
+ crit: 2,
514
+ error: 3,
515
+ warning: 4,
516
+ notice: 5,
517
+ info: 6,
518
+ debug: 7
519
+ }
520
+ ```
521
+
522
+ Similarly, `npm` logging levels are prioritized from 0 to 6 (highest to
523
+ lowest):
524
+
525
+ ``` js
526
+ {
527
+ error: 0,
528
+ warn: 1,
529
+ info: 2,
530
+ http: 3,
531
+ verbose: 4,
532
+ debug: 5,
533
+ silly: 6
534
+ }
535
+ ```
536
+
537
+ If you do not explicitly define the levels that `winston` should use, the
538
+ `npm` levels above will be used.
539
+
540
+ ### Using Logging Levels
541
+
542
+ Setting the level for your logging message can be accomplished in one of two
543
+ ways. You can pass a string representing the logging level to the log() method
544
+ or use the level specified methods defined on every winston Logger.
545
+
546
+ ``` js
547
+ //
548
+ // Any logger instance
549
+ //
550
+ logger.log('silly', "127.0.0.1 - there's no place like home");
551
+ logger.log('debug', "127.0.0.1 - there's no place like home");
552
+ logger.log('verbose', "127.0.0.1 - there's no place like home");
553
+ logger.log('info', "127.0.0.1 - there's no place like home");
554
+ logger.log('warn', "127.0.0.1 - there's no place like home");
555
+ logger.log('error', "127.0.0.1 - there's no place like home");
556
+ logger.info("127.0.0.1 - there's no place like home");
557
+ logger.warn("127.0.0.1 - there's no place like home");
558
+ logger.error("127.0.0.1 - there's no place like home");
559
+
560
+ //
561
+ // Default logger
562
+ //
563
+ winston.log('info', "127.0.0.1 - there's no place like home");
564
+ winston.info("127.0.0.1 - there's no place like home");
565
+ ```
566
+
567
+ `winston` allows you to define a `level` property on each transport which
568
+ specifies the **maximum** level of messages that a transport should log. For
569
+ example, using the `syslog` levels you could log only `error` messages to the
570
+ console and everything `info` and below to a file (which includes `error`
571
+ messages):
572
+
573
+ ``` js
574
+ const logger = winston.createLogger({
575
+ levels: winston.config.syslog.levels,
576
+ transports: [
577
+ new winston.transports.Console({ level: 'error' }),
578
+ new winston.transports.File({
579
+ filename: 'combined.log',
580
+ level: 'info'
581
+ })
582
+ ]
583
+ });
584
+ ```
585
+
586
+ You may also dynamically change the log level of a transport:
587
+
588
+ ``` js
589
+ const transports = {
590
+ console: new winston.transports.Console({ level: 'warn' }),
591
+ file: new winston.transports.File({ filename: 'combined.log', level: 'error' })
592
+ };
593
+
594
+ const logger = winston.createLogger({
595
+ transports: [
596
+ transports.console,
597
+ transports.file
598
+ ]
599
+ });
600
+
601
+ logger.info('Will not be logged in either transport!');
602
+ transports.console.level = 'info';
603
+ transports.file.level = 'info';
604
+ logger.info('Will be logged in both transports!');
605
+ ```
606
+
607
+ `winston` supports customizable logging levels, defaulting to npm style
608
+ logging levels. Levels must be specified at the time of creating your logger.
609
+
610
+ ### Using Custom Logging Levels
611
+
612
+ In addition to the predefined `npm`, `syslog`, and `cli` levels available in
613
+ `winston`, you can also choose to define your own:
614
+
615
+ ``` js
616
+ const myCustomLevels = {
617
+ levels: {
618
+ foo: 0,
619
+ bar: 1,
620
+ baz: 2,
621
+ foobar: 3
622
+ },
623
+ colors: {
624
+ foo: 'blue',
625
+ bar: 'green',
626
+ baz: 'yellow',
627
+ foobar: 'red'
628
+ }
629
+ };
630
+
631
+ const customLevelLogger = winston.createLogger({
632
+ levels: myCustomLevels.levels
633
+ });
634
+
635
+ customLevelLogger.foobar('some foobar level-ed message');
636
+ ```
637
+
638
+ Although there is slight repetition in this data structure, it enables simple
639
+ encapsulation if you do not want to have colors. If you do wish to have
640
+ colors, in addition to passing the levels to the Logger itself, you must make
641
+ winston aware of them:
642
+
643
+ ``` js
644
+ winston.addColors(myCustomLevels.colors);
645
+ ```
646
+
647
+ This enables loggers using the `colorize` formatter to appropriately color and style
648
+ the output of custom levels.
649
+
650
+ Additionally, you can also change background color and font style.
651
+ For example,
652
+ ``` js
653
+ baz: 'italic yellow',
654
+ foobar: 'bold red cyanBG'
655
+ ```
656
+
657
+ Possible options are below.
658
+
659
+ * Font styles: `bold`, `dim`, `italic`, `underline`, `inverse`, `hidden`,
660
+ `strikethrough`.
661
+
662
+ * Font foreground colors: `black`, `red`, `green`, `yellow`, `blue`, `magenta`,
663
+ `cyan`, `white`, `gray`, `grey`.
664
+
665
+ * Background colors: `blackBG`, `redBG`, `greenBG`, `yellowBG`, `blueBG`
666
+ `magentaBG`, `cyanBG`, `whiteBG`
667
+
668
+ ### Colorizing Standard logging levels
669
+
670
+ To colorize the standard logging level add
671
+ ```js
672
+ winston.format.combine(
673
+ winston.format.colorize(),
674
+ winston.format.json()
675
+ );
676
+ ```
677
+ where `winston.format.json()` is whatever other formatter you want to use. The `colorize` formatter must come before any formatters adding text you wish to color.
678
+
679
+ ## Transports
680
+
681
+ There are several [core transports] included in `winston`, which leverage the
682
+ built-in networking and file I/O offered by Node.js core. In addition, there
683
+ are [additional transports] written by members of the community.
684
+
685
+ ## Multiple transports of the same type
686
+
687
+ It is possible to use multiple transports of the same type e.g.
688
+ `winston.transports.File` when you construct the transport.
689
+
690
+ ``` js
691
+ const logger = winston.createLogger({
692
+ transports: [
693
+ new winston.transports.File({
694
+ filename: 'combined.log',
695
+ level: 'info'
696
+ }),
697
+ new winston.transports.File({
698
+ filename: 'errors.log',
699
+ level: 'error'
700
+ })
701
+ ]
702
+ });
703
+ ```
704
+
705
+ If you later want to remove one of these transports you can do so by using the
706
+ transport itself. e.g.:
707
+
708
+ ``` js
709
+ const combinedLogs = logger.transports.find(transport => {
710
+ return transport.filename === 'combined.log'
711
+ });
712
+
713
+ logger.remove(combinedLogs);
714
+ ```
715
+
716
+ ## Adding Custom Transports
717
+
718
+ Adding a custom transport is easy. All you need to do is accept any options
719
+ you need, implement a log() method, and consume it with `winston`.
720
+
721
+ ``` js
722
+ const Transport = require('winston-transport');
723
+ const util = require('util');
724
+
725
+ //
726
+ // Inherit from `winston-transport` so you can take advantage
727
+ // of the base functionality and `.exceptions.handle()`.
728
+ //
729
+ module.exports = class YourCustomTransport extends Transport {
730
+ constructor(opts) {
731
+ super(opts);
732
+ //
733
+ // Consume any custom options here. e.g.:
734
+ // - Connection information for databases
735
+ // - Authentication information for APIs (e.g. loggly, papertrail,
736
+ // logentries, etc.).
737
+ //
738
+ }
739
+
740
+ log(info, callback) {
741
+ setImmediate(() => {
742
+ this.emit('logged', info);
743
+ });
744
+
745
+ // Perform the writing to the remote service
746
+ callback();
747
+ }
748
+ };
749
+ ```
750
+
751
+ ## Common Transport options
752
+
753
+ As every transport inherits from [winston-transport], it's possible to set
754
+ a custom format and a custom log level on each transport separately:
755
+
756
+ ``` js
757
+ const logger = winston.createLogger({
758
+ transports: [
759
+ new winston.transports.File({
760
+ filename: 'error.log',
761
+ level: 'error',
762
+ format: winston.format.json()
763
+ }),
764
+ new transports.Http({
765
+ level: 'warn',
766
+ format: winston.format.json()
767
+ }),
768
+ new transports.Console({
769
+ level: 'info',
770
+ format: winston.format.combine(
771
+ winston.format.colorize(),
772
+ winston.format.simple()
773
+ )
774
+ })
775
+ ]
776
+ });
777
+ ```
778
+
779
+ ## Exceptions
780
+
781
+ ### Handling Uncaught Exceptions with winston
782
+
783
+ With `winston`, it is possible to catch and log `uncaughtException` events
784
+ from your process. With your own logger instance you can enable this behavior
785
+ when it's created or later on in your applications lifecycle:
786
+
787
+ ``` js
788
+ const { createLogger, transports } = require('winston');
789
+
790
+ // Enable exception handling when you create your logger.
791
+ const logger = createLogger({
792
+ transports: [
793
+ new transports.File({ filename: 'combined.log' })
794
+ ],
795
+ exceptionHandlers: [
796
+ new transports.File({ filename: 'exceptions.log' })
797
+ ]
798
+ });
799
+
800
+ // Or enable it later on by adding a transport or using `.exceptions.handle`
801
+ const logger = createLogger({
802
+ transports: [
803
+ new transports.File({ filename: 'combined.log' })
804
+ ]
805
+ });
806
+
807
+ // Call exceptions.handle with a transport to handle exceptions
808
+ logger.exceptions.handle(
809
+ new transports.File({ filename: 'exceptions.log' })
810
+ );
811
+ ```
812
+
813
+ If you want to use this feature with the default logger, simply call
814
+ `.exceptions.handle()` with a transport instance.
815
+
816
+ ``` js
817
+ //
818
+ // You can add a separate exception logger by passing it to `.exceptions.handle`
819
+ //
820
+ winston.exceptions.handle(
821
+ new winston.transports.File({ filename: 'path/to/exceptions.log' })
822
+ );
823
+
824
+ //
825
+ // Alternatively you can set `handleExceptions` to true when adding transports
826
+ // to winston.
827
+ //
828
+ winston.add(new winston.transports.File({
829
+ filename: 'path/to/combined.log',
830
+ handleExceptions: true
831
+ }));
832
+ ```
833
+
834
+ ### To Exit or Not to Exit
835
+
836
+ By default, winston will exit after logging an uncaughtException. If this is
837
+ not the behavior you want, set `exitOnError = false`
838
+
839
+ ``` js
840
+ const logger = winston.createLogger({ exitOnError: false });
841
+
842
+ //
843
+ // or, like this:
844
+ //
845
+ logger.exitOnError = false;
846
+ ```
847
+
848
+ When working with custom logger instances, you can pass in separate transports
849
+ to the `exceptionHandlers` property or set `handleExceptions` on any
850
+ transport.
851
+
852
+ ##### Example 1
853
+
854
+ ``` js
855
+ const logger = winston.createLogger({
856
+ transports: [
857
+ new winston.transports.File({ filename: 'path/to/combined.log' })
858
+ ],
859
+ exceptionHandlers: [
860
+ new winston.transports.File({ filename: 'path/to/exceptions.log' })
861
+ ]
862
+ });
863
+ ```
864
+
865
+ ##### Example 2
866
+
867
+ ``` js
868
+ const logger = winston.createLogger({
869
+ transports: [
870
+ new winston.transports.Console({
871
+ handleExceptions: true
872
+ })
873
+ ],
874
+ exitOnError: false
875
+ });
876
+ ```
877
+
878
+ The `exitOnError` option can also be a function to prevent exit on only
879
+ certain types of errors:
880
+
881
+ ``` js
882
+ function ignoreEpipe(err) {
883
+ return err.code !== 'EPIPE';
884
+ }
885
+
886
+ const logger = winston.createLogger({ exitOnError: ignoreEpipe });
887
+
888
+ //
889
+ // or, like this:
890
+ //
891
+ logger.exitOnError = ignoreEpipe;
892
+ ```
893
+
894
+ ## Rejections
895
+
896
+ ### Handling Uncaught Promise Rejections with winston
897
+
898
+ With `winston`, it is possible to catch and log `uncaughtRejection` events
899
+ from your process. With your own logger instance you can enable this behavior
900
+ when it's created or later on in your applications lifecycle:
901
+
902
+ ``` js
903
+ const { createLogger, transports } = require('winston');
904
+
905
+ // Enable rejection handling when you create your logger.
906
+ const logger = createLogger({
907
+ transports: [
908
+ new transports.File({ filename: 'combined.log' })
909
+ ],
910
+ rejectionHandlers: [
911
+ new transports.File({ filename: 'rejections.log' })
912
+ ]
913
+ });
914
+
915
+ // Or enable it later on by adding a transport or using `.rejections.handle`
916
+ const logger = createLogger({
917
+ transports: [
918
+ new transports.File({ filename: 'combined.log' })
919
+ ]
920
+ });
921
+
922
+ // Call rejections.handle with a transport to handle rejections
923
+ logger.rejections.handle(
924
+ new transports.File({ filename: 'rejections.log' })
925
+ );
926
+ ```
927
+
928
+ If you want to use this feature with the default logger, simply call
929
+ `.rejections.handle()` with a transport instance.
930
+
931
+ ``` js
932
+ //
933
+ // You can add a separate rejection logger by passing it to `.rejections.handle`
934
+ //
935
+ winston.rejections.handle(
936
+ new winston.transports.File({ filename: 'path/to/rejections.log' })
937
+ );
938
+
939
+ //
940
+ // Alternatively you can set `handleRejections` to true when adding transports
941
+ // to winston.
942
+ //
943
+ winston.add(new winston.transports.File({
944
+ filename: 'path/to/combined.log',
945
+ handleRejections: true
946
+ }));
947
+ ```
948
+
949
+ ## Profiling
950
+
951
+ In addition to logging messages and metadata, `winston` also has a simple
952
+ profiling mechanism implemented for any logger:
953
+
954
+ ``` js
955
+ //
956
+ // Start profile of 'test'
957
+ //
958
+ logger.profile('test');
959
+
960
+ setTimeout(function () {
961
+ //
962
+ // Stop profile of 'test'. Logging will now take place:
963
+ // '17 Jan 21:00:00 - info: test duration=1000ms'
964
+ //
965
+ logger.profile('test');
966
+ }, 1000);
967
+ ```
968
+
969
+ Also you can start a timer and keep a reference that you can call `.done()``
970
+ on:
971
+
972
+ ``` js
973
+ // Returns an object corresponding to a specific timing. When done
974
+ // is called the timer will finish and log the duration. e.g.:
975
+ //
976
+ const profiler = logger.startTimer();
977
+ setTimeout(function () {
978
+ profiler.done({ message: 'Logging message' });
979
+ }, 1000);
980
+ ```
981
+
982
+ All profile messages are set to 'info' level by default, and both message and
983
+ metadata are optional. For individual profile messages, you can override the default log level by supplying a metadata object with a `level` property:
984
+
985
+ ```js
986
+ logger.profile('test', { level: 'debug' });
987
+ ```
988
+
989
+ ## Querying Logs
990
+
991
+ `winston` supports querying of logs with Loggly-like options. [See Loggly
992
+ Search API](https://www.loggly.com/docs/api-retrieving-data/). Specifically:
993
+ `File`, `Couchdb`, `Redis`, `Loggly`, `Nssocket`, and `Http`.
994
+
995
+ ``` js
996
+ const options = {
997
+ from: new Date() - (24 * 60 * 60 * 1000),
998
+ until: new Date(),
999
+ limit: 10,
1000
+ start: 0,
1001
+ order: 'desc',
1002
+ fields: ['message']
1003
+ };
1004
+
1005
+ //
1006
+ // Find items logged between today and yesterday.
1007
+ //
1008
+ logger.query(options, function (err, results) {
1009
+ if (err) {
1010
+ /* TODO: handle me */
1011
+ throw err;
1012
+ }
1013
+
1014
+ console.log(results);
1015
+ });
1016
+ ```
1017
+
1018
+ ## Streaming Logs
1019
+ Streaming allows you to stream your logs back from your chosen transport.
1020
+
1021
+ ``` js
1022
+ //
1023
+ // Start at the end.
1024
+ //
1025
+ winston.stream({ start: -1 }).on('log', function(log) {
1026
+ console.log(log);
1027
+ });
1028
+ ```
1029
+
1030
+ ## Further Reading
1031
+
1032
+ ### Using the Default Logger
1033
+
1034
+ The default logger is accessible through the `winston` module directly. Any
1035
+ method that you could call on an instance of a logger is available on the
1036
+ default logger:
1037
+
1038
+ ``` js
1039
+ const winston = require('winston');
1040
+
1041
+ winston.log('info', 'Hello distributed log files!');
1042
+ winston.info('Hello again distributed logs');
1043
+
1044
+ winston.level = 'debug';
1045
+ winston.log('debug', 'Now my debug messages are written to console!');
1046
+ ```
1047
+
1048
+ By default, no transports are set on the default logger. You must
1049
+ add or remove transports via the `add()` and `remove()` methods:
1050
+
1051
+ ``` js
1052
+ const files = new winston.transports.File({ filename: 'combined.log' });
1053
+ const console = new winston.transports.Console();
1054
+
1055
+ winston.add(console);
1056
+ winston.add(files);
1057
+ winston.remove(console);
1058
+ ```
1059
+
1060
+ Or do it with one call to configure():
1061
+
1062
+ ``` js
1063
+ winston.configure({
1064
+ transports: [
1065
+ new winston.transports.File({ filename: 'somefile.log' })
1066
+ ]
1067
+ });
1068
+ ```
1069
+
1070
+ For more documentation about working with each individual transport supported
1071
+ by `winston` see the [`winston` Transports](docs/transports.md) document.
1072
+
1073
+ ### Awaiting logs to be written in `winston`
1074
+
1075
+ Often it is useful to wait for your logs to be written before exiting the
1076
+ process. Each instance of `winston.Logger` is also a [Node.js stream]. A
1077
+ `finish` event will be raised when all logs have flushed to all transports
1078
+ after the stream has been ended.
1079
+
1080
+ ``` js
1081
+ const transport = new winston.transports.Console();
1082
+ const logger = winston.createLogger({
1083
+ transports: [transport]
1084
+ });
1085
+
1086
+ logger.on('finish', function (info) {
1087
+ // All `info` log messages has now been logged
1088
+ });
1089
+
1090
+ logger.info('CHILL WINSTON!', { seriously: true });
1091
+ logger.end();
1092
+ ```
1093
+
1094
+ It is also worth mentioning that the logger also emits an 'error' event which
1095
+ you should handle or suppress if you don't want unhandled exceptions:
1096
+
1097
+ ``` js
1098
+ //
1099
+ // Handle errors
1100
+ //
1101
+ logger.on('error', function (err) { /* Do Something */ });
1102
+ ```
1103
+
1104
+ ### Working with multiple Loggers in winston
1105
+
1106
+ Often in larger, more complex, applications it is necessary to have multiple
1107
+ logger instances with different settings. Each logger is responsible for a
1108
+ different feature area (or category). This is exposed in `winston` in two
1109
+ ways: through `winston.loggers` and instances of `winston.Container`. In fact,
1110
+ `winston.loggers` is just a predefined instance of `winston.Container`:
1111
+
1112
+ ``` js
1113
+ const winston = require('winston');
1114
+ const { format } = winston;
1115
+ const { combine, label, json } = format;
1116
+
1117
+ //
1118
+ // Configure the logger for `category1`
1119
+ //
1120
+ winston.loggers.add('category1', {
1121
+ format: combine(
1122
+ label({ label: 'category one' }),
1123
+ json()
1124
+ ),
1125
+ transports: [
1126
+ new winston.transports.Console({ level: 'silly' }),
1127
+ new winston.transports.File({ filename: 'somefile.log' })
1128
+ ]
1129
+ });
1130
+
1131
+ //
1132
+ // Configure the logger for `category2`
1133
+ //
1134
+ winston.loggers.add('category2', {
1135
+ format: combine(
1136
+ label({ label: 'category two' }),
1137
+ json()
1138
+ ),
1139
+ transports: [
1140
+ new winston.transports.Http({ host: 'localhost', port:8080 })
1141
+ ]
1142
+ });
1143
+ ```
1144
+
1145
+ Now that your loggers are setup, you can require winston _in any file in your
1146
+ application_ and access these pre-configured loggers:
1147
+
1148
+ ``` js
1149
+ const winston = require('winston');
1150
+
1151
+ //
1152
+ // Grab your preconfigured loggers
1153
+ //
1154
+ const category1 = winston.loggers.get('category1');
1155
+ const category2 = winston.loggers.get('category2');
1156
+
1157
+ category1.info('logging to file and console transports');
1158
+ category2.info('logging to http transport');
1159
+ ```
1160
+
1161
+ If you prefer to manage the `Container` yourself, you can simply instantiate one:
1162
+
1163
+ ``` js
1164
+ const winston = require('winston');
1165
+ const { format } = winston;
1166
+ const { combine, label, json } = format;
1167
+
1168
+ const container = new winston.Container();
1169
+
1170
+ container.add('category1', {
1171
+ format: combine(
1172
+ label({ label: 'category one' }),
1173
+ json()
1174
+ ),
1175
+ transports: [
1176
+ new winston.transports.Console({ level: 'silly' }),
1177
+ new winston.transports.File({ filename: 'somefile.log' })
1178
+ ]
1179
+ });
1180
+
1181
+ const category1 = container.get('category1');
1182
+ category1.info('logging to file and console transports');
1183
+ ```
1184
+
1185
+ ## Installation
1186
+
1187
+ ``` bash
1188
+ npm install winston
1189
+ ```
1190
+
1191
+ ``` bash
1192
+ yarn add winston
1193
+ ```
1194
+
1195
+ ## Run Tests
1196
+
1197
+ All of the winston tests are written with [`mocha`][mocha], [`nyc`][nyc], and
1198
+ [`assume`][assume]. They can be run with `npm`.
1199
+
1200
+ ``` bash
1201
+ npm test
1202
+ ```
1203
+
1204
+ #### Author: [Charlie Robbins]
1205
+ #### Contributors: [Jarrett Cruger], [David Hyde], [Chris Alderson]
1206
+
1207
+ [Transports]: #transports
1208
+ [Logging levels]: #logging-levels
1209
+ [Formats]: #formats
1210
+ [Using custom logging levels]: #using-custom-logging-levels
1211
+ [Adding Custom Transports]: #adding-custom-transports
1212
+ [core transports]: docs/transports.md#winston-core
1213
+ [additional transports]: docs/transports.md#additional-transports
1214
+
1215
+ [RFC5424]: https://tools.ietf.org/html/rfc5424
1216
+ [util.format]: https://nodejs.org/dist/latest/docs/api/util.html#util_util_format_format_args
1217
+ [mocha]: https://mochajs.org
1218
+ [nyc]: https://github.com/istanbuljs/nyc
1219
+ [assume]: https://github.com/bigpipe/assume
1220
+ [logform]: https://github.com/winstonjs/logform#readme
1221
+ [winston-transport]: https://github.com/winstonjs/winston-transport
1222
+
1223
+ [Read the `winston@2.x` documentation]: https://github.com/winstonjs/winston/tree/2.x
1224
+
1225
+ [quick-example]: https://github.com/winstonjs/winston/blob/master/examples/quick-start.js
1226
+ [examples]: https://github.com/winstonjs/winston/tree/master/examples
1227
+
1228
+ [Charlie Robbins]: http://github.com/indexzero
1229
+ [Jarrett Cruger]: https://github.com/jcrugzz
1230
+ [David Hyde]: https://github.com/dabh
1231
+ [Chris Alderson]: https://github.com/chrisalderson