UNPKG

8.57 kBMarkdownView Raw
1# Ignition
2
3![Build Status](https://github.com/TryGhost/Ignition/workflows/Test/badge.svg?branch=master)
4
5Basic configuration and tooling shared across applications
6
7# Install
8
9`npm install ghost-ignition --save`
10
11or
12
13`yarn add ghost-ignition`
14
15# Usage
16
17Ignition offers the following features:
18
19- Logging
20- Errors
21- Config using nconf
22- HTTP Server
23- Debug
24
25## Logging
26
27### Configuration
28
29|Property|Type|Required|Default|Description|
30|---|---|---|---|---|
31|domain|String|No|'localhost'| The domain of your service. The domain is used to generate the log filenames.|
32|env|String|No|'development'| The environment is used for to generate the log filenames.
33|mode|String|No|'short'| A specific option for stdout/stderr logging. You can configure if the logger should log with "long" (many information) or "short" (less information) output.
34|level|String|No|'info'| Configure the default log level. The log level ("info", "warn", "error") defines which logs should be piped into stdout and log files.
35|transports|Array|No|['stdout']| A comma separated list of transports. Available transports are: file, stdout, stderr, loggly, gelf
36|rotation|Object|No|{enabled: true, period: '1w', count: 100}| If file transport is enabled, you can configure if you would like to enable log rotation.
37|path|String|No|process.cwd()| If file transport is enabled, the path config can be used to define the target log folder.
38|loggly|Object|No|null| If loggly transport is enabled, you can send your logs to loggly.
39|gelf|Object|No|null| If GELF transport is enabled, you can send your logs to GELF collector.
40
41Example:
42
43```js
44const ignition = require('ghost-ignition');
45
46const logging = ignition.logging({
47 domain: 'example.com',
48 env: 'production',
49 mode: 'long',
50 level: 'info',
51 transports: ['file'],
52 rotation: {enabled: true, period: '1d', count: 10},
53 path: '/var/log'
54});
55```
56
57### Examples
58
59```js
60logging.info({req: req, res: res});
61logging.info({req: req, res: res, err: err});
62logging.info('Info');
63logging.error(new Error());
64logging.warn('this', 'is', 'a', 'warning');
65logging.debug('this is a debug mode');
66logging.warn(err, 'Caught an error from service X.');
67logging.warn('A friendly message.', err);
68logging.warn('A friendly message.', {err: err});
69```
70
71### Transports
72
73#### File
74
75Ignition creates two log files by default:
76
77- An errors log file, which only contains logs from `logging.error`
78- A general log file, which contains all logs from `logging.info`, `logging.warn` and `logging.error`
79
80If you would like to open a log file on disk, we highly recommend to install bunyan with NPM (`npm i -g bunyan`).
81You can then open your log file with `bunyan your.log` in the shell, which makes it possible to read the content.
82
83#### Loggly
84
85The loggly transport makes it possible to send your logs to loggly.
86The stream will only send errors to loggly at the moment.
87
88Example:
89
90```js
91const ignition = require('ghost-ignition');
92
93const logging = ignition.logging({
94 transports: ['file', 'loggly'],
95 loggly: {
96 token: 'token',
97 subdomain: 'subdomain',
98 // The "match" property is helpful if you only want to send specific errors to loggly. It's a regex string.
99 match: 'level:critical' // or 'statusCode:500|statusCode:403'
100 },
101 ...
102});
103```
104
105#### GELF
106
107The transport makes it possible to send logs to the GELF UDP collector.
108
109Example:
110
111```
112const ignition = require('ghost-ignition');
113
114const logging = ignition.logging({
115 transports: ['gelf'],
116 gelf: {
117 host: 'gelf.example.com', // Default: '127.0.0.1'
118 post: 12345 // Default: 12201
119 },
120 ...
121});
122```
123
124### Shell
125
126#### ENV Variables
127
128Ignition accepts some env variables to modify the log output.
129
130`LEVEL=error` - Only print errors.
131`MODE=long` - Show full & long log output.
132`LOIN=true` - Set's the level to "info" and the mode to "long".
133
134## Errors
135
136Ignition errors contains a set of useful & common error classes.
137Each Ignition error inherits from [Node's native error](https://nodejs.org/api/errors.html#errors_class_error) and keeps the structure!
138
139### Extra properties
140
141On top of the native error properties (message, code, stack), Ignition errors support the following properties:
142
143|Property|Description
144|---|---|
145|id|A unique error ID, which every error get's attached.
146|statusCode|The HTTP status code.
147|level|Indicates if an error is "critical" or "normal".
148|errorType|Name/type of the error.
149|context|Context the error is in e.g. user was logged in
150|help|This property is useful to e.g. show a link to docs.
151|errorDetails|Extra detailed information you can pass in.
152
153### List of errors
154
155|Error|Status Code|Level|Description
156|---|---|---|---|
157|InternalServerError|500|critical|Common error for internal errors.
158|IncorrectUsageError|400|critical|Mis-usage inside the code base.
159|NotFoundError|404|normal|Common error if a resource/page cannot be found.
160|BadRequestError|400|normal|Common error if the request structure is wrong.
161|UnauthorizedError|401|normal|Common error if authentication failed.
162|NoPermissionError|403|normal|Common error if the request has no permissions.
163|ValidationError|422|normal|Common error if the request input/content is invalid.
164|UnsupportedMediaTypeError|415|normal|Common error if the media inside a request is unsupported.
165|TooManyRequestsError|429|normal|Common error for handling brute forcing.
166|MaintenanceError|503|normal|Helpful error if your application is in maintenance mode.
167|MethodNotAllowedError|405|normal|Helpful error if e.g. the request method is unsupported.
168|RequestEntityTooLargeError|413|normal|Helpful error if file upload is too big.
169
170### Examples
171
172```js
173new logging.errors.InternalServerError({
174 message: 'Something went very wrong',
175 context: {
176 user: 1
177 }
178})
179
180// Ignition supports nested errors. It will try to inherit properties and extend the stack trace.
181// This is super useful if you receive an error from a calling unit, but you would like to wrap it into a custom error.
182new logging.errors.InternalServerError({
183 err: err
184})
185```
186
187### Error utils
188
189```js
190const ignition = require('ghost-ignition');
191
192// you can pass any error and ignition will tell you if this is a custom ignition error
193ignition.errors.utils.isIgnitionError(err);
194
195// serialize an error to a specific format
196ignition.errors.utils.serialize(err, {format: 'jsonapi|oauth'});
197
198// deserialize specific format to error instance
199ignition.errors.utils.deserialize(err);
200```
201
202## Config
203
204Ignition config uses nconf to create a configuration object based on your environment.
205
206### Requirements
207
208- Create config files based on your available environments.
209- Instantiate Ignition config.
210- Read [nconf documentation](https://github.com/indexzero/nconf#readme) to understand how to use the config object.
211
212### Examples
213
214config.example.json (defaults)
215```json
216{
217 "port": 9999
218}
219```
220
221config.production.json
222```json
223{
224 "host": "blog.com"
225}
226```
227
228config.development.json
229```json
230{
231 "host": "localhost"
232}
233```
234
235```js
236// As soon as you call the config object, Ignition will read your config files from disk and returns a config object.
237// The config object is then cached. You can operate on the config object using `set` and `get` (see [nconf](https://github.com/indexzero/nconf#readme))
238const config = require('ghost-ignition').config();
239
240// -> {port: 9999, host: localhost}
241```
242
243## Debug
244
245Ignition debug offers an easy way to add debugging to your application.
246It wraps the [debug](https://github.com/visionmedia/debug#readme) NPM module to simplify how to add debug information to your files.
247Ignition debug will try to read your package.json to get the name/alias of your application.
248You can enable the debug log by passing the "DEBUG" environment variable.
249
250### Requirements
251
252- Read [debug documentation](https://github.com/visionmedia/debug#readme).
253
254
255### Examples
256
257package.json
258```json
259 "name": "myproject",
260 "alias": "proj"
261```
262
263```js
264const debug = require('ghost-ignition').debug('api-controller');
265
266debug('Calling the model layer.');
267
268// DEBUG=proj:api-controller yarn start
269```
270
271## Server
272
273The HTTP server bundles common logic in one place.
274
275- error handling for the HTTP server
276- port normalisation
277
278### Requirements
279
280- Express
281- Ignition config
282
283### Examples
284
285```js
286const ignition = require('ghost-ignition');
287ignition.server.start(app);
288ignition.server.stop(app);
289```
290
291# Test
292
293- `yarn lint` run just eslint
294- `yarn test` run eslint && then tests
295
296# Publish
297
298- `yarn ship`
299
300# Copyright & License
301
302Copyright (c) 2013-2021 Ghost Foundation - Released under the [MIT license](LICENSE).