UNPKG

12.4 kBMarkdownView Raw
1# advanced-logger
2
3[![Build Status](https://travis-ci.org/AlexeyPopovUA/advanced-logger.svg?branch=master)](https://travis-ci.org/AlexeyPopovUA/advanced-logger)
4[![npm version](https://badge.fury.io/js/advanced-logger.svg)](https://badge.fury.io/js/advanced-logger)
5[![dependencies Status](https://david-dm.org/AlexeyPopovUA/advanced-logger/status.svg)](https://david-dm.org/AlexeyPopovUA/advanced-logger)
6[![install size](https://packagephobia.now.sh/badge?p=advanced-logger)](https://packagephobia.now.sh/result?p=advanced-logger)
7[![](https://data.jsdelivr.com/v1/package/npm/advanced-logger/badge)](https://www.jsdelivr.com/package/npm/advanced-logger)
8[![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%2FAlexeyPopovUA%2Fadvanced-logger.svg?type=shield)](https://app.fossa.io/projects/git%2Bgithub.com%2FAlexeyPopovUA%2Fadvanced-logger?ref=badge_shield)
9
10[![Quality Gate](https://sonarcloud.io/api/project_badges/measure?project=advanced-logger&metric=alert_status)](https://sonarcloud.io/dashboard/index/advanced-logger)
11[![Reliability](https://sonarcloud.io/api/project_badges/measure?project=advanced-logger&metric=reliability_rating)](https://sonarcloud.io/dashboard/index/advanced-logger)
12[![Coverage](https://sonarcloud.io/api/project_badges/measure?project=advanced-logger&metric=coverage)](https://sonarcloud.io/dashboard/index/advanced-logger)
13[![Bugs](https://sonarcloud.io/api/project_badges/measure?project=advanced-logger&metric=bugs)](https://sonarcloud.io/dashboard/index/advanced-logger)
14[![Code Smells](https://sonarcloud.io/api/project_badges/measure?project=advanced-logger&metric=code_smells)](https://sonarcloud.io/dashboard/index/advanced-logger)
15[![Vulnerabilities](https://sonarcloud.io/api/project_badges/measure?project=advanced-logger&metric=vulnerabilities)](https://sonarcloud.io/dashboard/index/advanced-logger)
16[![Conventional Commits](https://img.shields.io/badge/Conventional%20Commits-1.0.0-yellow.svg)](https://conventionalcommits.org)
17
18## The idea
19
20The main idea of this module is to create an isomorphic log sending tool, that can be extended by internal/external plugins.
21
22It has bundles for browser and nodejs environments.
23
24It can be extended with custom strategy ("when to send logs") and service ("where to send logs"). See usage examples.
25
26It does not restrict you with conventions, for example, existence of "logSeverity", "ErrorId" or "message" fields in log.
27
28It supports any format of logs via custom serializer.
29
30## Features
31
32* It works in browsers and nodejs
33* It is able to send single logs and bundles of them to an external logger
34* It supports different log sending strategies:
35 1. interval (for example, every 10 seconds)
36 2. on request (only when you ask)
37 3. mixed ("interval" + "on request") (will be done soon)
38 4. on bundle size (for example, sends bundles of 100 logs)
39 5. instant (received 1 log -> sent 1 log)
40* It is able to group duplicated logs in certain time interval (for rapid fire of the same logs)
41* It is not afraid of circular links in log objects
42* It supports custom format for logs (custom serializer)
43* It supports different remote logger endpoints (SumoLogic, Loggly and Elasticsearch). Who is the next? ᕙ(ಠ.ಠ)ᕗ
44
45## Runtime environment support
46
47Builds are generated as ES5 bundles for nodejs and browser environments.
48
49NodeJS - tested on latest lts
50
51Browser - all latest browsers + IE10, IE11 (fetch polyfill)
52
53## Usage
54
55Please, find working examples for browser and nodejs environments in **/example** folder.
56
57### Add to the project
58
59In browser:
60
61```html
62<script src="./node-modules/advance-logger/dist/browser/advanced-logger.browser.min.js"></script>
63```
64
65or
66
67```html
68<script src="https://cdn.jsdelivr.net/npm/advanced-logger@latest/dist/browser/advanced-logger.browser.min.js"></script>
69<script src="https://cdn.jsdelivr.net/npm/advanced-logger@latest/dist/browser-debug/advanced-logger.browser.js"></script>
70```
71
72In nodejs:
73
74```javascript
75const {AdvancedLogger, service, strategy} = require('advanced-logger');
76```
77
78### Simplest usage
79
80Lets initiate a logger that sends all logs instantly to Sumologic service.
81
82In browser
83
84```javascript
85const {AdvancedLogger, service, strategy} = window.advancedLogger;
86
87const defaultLogConfig = {
88 UserAgent: window.userAgent,
89 Channel: "my-company",
90 BuildVersion: 123,
91 Platform: "browser",
92 Severity: "DEBUG",
93 Data: "",
94 Timestamp: "",
95 Message: "",
96 Category: ""
97};
98
99const serviceConfig = {
100 url: "https://www.google.nl",
101 sourceName: "advancedLoggerTest",
102 host: "advanced-logger",
103 sourceCategory: "MY/SUMO/namespace",
104 method: "POST"
105};
106
107const config = {serviceConfig, defaultLogConfig};
108
109const logger = new AdvancedLogger({
110 service: new service.SumologicService(config),
111 strategy: new strategy.InstantStrategy()
112});
113
114logger.log({test: "instant log u1"});
115logger.log({test: "instant log u2"});
116logger.log({test: "instant log u3"});
117```
118
119### Strategies
120
121Strategies are components that "know" when is it right time to send logs.
122
123There are next strategies available:
124
125* InstantStrategy
126* OnBundleSizeStrategy
127* OnIntervalStrategy
128* OnRequestStrategy
129
130#### InstantStrategy
131
132Does not require parameters. It just sends the log as soon as it appears in logger.
133
134```javascript
135const {strategy} = require("advanced-logger");
136const strategy = new strategy.InstantStrategy();
137```
138
139#### OnBundleSizeStrategy
140
141Can accept a configuration object with an optional "maxBundle" value, which determines what is a maximal amount of logs it should collect before sending to the service. Default number is 100.
142
143```javascript
144const {strategy} = require("advanced-logger");
145const config = {
146 maxBundle: 123
147};
148const strategy = new strategy.OnBundleSizeStrategy(config);
149```
150
151#### OnIntervalStrategy
152
153Can accept a configuration object with an optional "interval" value, which determines what is a time interval for collecting logs before sending them to the service. Default number is 15000.
154
155```javascript
156const {strategy} = require("advanced-logger");
157const config = {
158 interval: 10000
159};
160const strategy = new strategy.OnIntervalStrategy(config);
161```
162
163#### OnRequestStrategy
164
165This strategy does not do anything :) . It will send logs only after manual call to ```logger.sendAllLogs();``` method.
166
167```javascript
168const {strategy} = require("advanced-logger");
169
170const strategy = new strategy.OnRequestStrategy();
171
172//"logger" is an instance of AdvancedLogger
173
174logger.sendAllLogs();
175```
176
177#### Custom implementation of strategy
178
179TODO
180
181### Services
182
183Currently, module supports only Sumologic and Loggly services out of the box.
184
185#### Sumologic (see https://www.sumologic.com/)
186
187```javascript
188//Configuration for communication with Sumologic.
189//Url should be taken from the logger's source category configuration page.
190const serviceConfig = {
191 url: "https://www.google.nl",
192 sourceName: "advancedLoggerTest",
193 host: "advanced-logger",
194 sourceCategory: "MY/SUMO/namespace",
195 method: "POST"
196};
197
198//Default log configuration.
199//It is used like a template with default values for each new log.
200//Can be of any structure. It will be shallowly copied during creation of a new log record.
201const defaultLogConfig = {
202 UserAgent: window.userAgent,
203 BuildVersion: 123,
204 Platform: "browser",
205 Severity: "DEBUG",
206 Data: "",
207 Timestamp: "",
208 Message: "",
209 Category: ""
210};
211
212//general config
213const config = {serviceConfig, defaultLogConfig};
214
215const service = new service.SumologicService(config);
216```
217
218#### Loggly (see https://www.loggly.com/)
219
220```javascript
221//Configuration for communication with Loggly.
222//Url should be taken from the logger's source category configuration page.
223const serviceConfig = {
224 // this should be the url for **bulk** log sending
225 url: "https://logs-01.loggly.com/bulk/<customertoken>/tag/bulk/",
226 method: "POST"
227};
228
229//Default log configuration.
230//It is used like a template with default values for each new log.
231//Can be of any structure. It will be shallowly copied during creation of a new log record.
232const defaultLogConfig = {
233 UserAgent: window.userAgent,
234 BuildVersion: 123,
235 Platform: "browser",
236 Severity: "DEBUG",
237 Data: "",
238 Timestamp: "",
239 Message: "",
240 Category: ""
241};
242
243//general config
244const config = {serviceConfig, defaultLogConfig};
245
246const service = new service.LogglyService(config);
247```
248
249#### Elastic Search Service (see https://docs.aws.amazon.com/elasticsearch-service/latest/developerguide/es-gsg-upload-data.html)
250
251Logger supports sending data to Elasticsearch service endpoint. It was tested on AWS-based instance of Elasticsearch and Kibana. Ideally, it should work also on instance of any other cloud provider.
252
253```javascript
254//Configuration for communication with Elastic Search.
255//Url should be taken from the logger's source category configuration page.
256const serviceConfig = {
257 // this should be the url for **bulk** log sending
258 url: "https://<endpoint_url>/_bulk",
259 method: "POST",
260 //this field will be used to send index value in meta information for each log
261 logMetaIndexField: "IndexField"
262};
263
264//Default log configuration.
265//It is used like a template with default values for each new log.
266//Can be of any structure. It will be shallowly copied during creation of a new log record.
267const defaultLogConfig = {
268 BuildVersion: 123,
269 Platform: "browser",
270 Severity: "DEBUG",
271 Data: "",
272 Timestamp: "",
273 Message: "",
274 IndexField: "web-app"
275};
276
277//general config
278const config = {serviceConfig, defaultLogConfig};
279
280const service = new service.ElasticsearchService(config);
281```
282
283#### Custom serializer
284
285There are situations when you need a "special" representation of logs instead of JSON before sending them to remote storage. For example, key-value pairs:
286
287```
288[Timestamp=1234567890] [Message="test message"] [Category="MyController"]
289```
290
291In order to serialize logs in your own way, you can use ```serializer``` configuration with services:
292
293```javascript
294const serializer = logObject =>
295 Object.keys(logObject)
296 .map(key => `[${key}=${JSON.stringify(logObject[key])}]`)
297 .join(" ");
298
299const configWithSerializer = {serviceConfig, defaultLogConfig, serializer};
300const testLogs = [
301 {test: "test123"},
302 {test: "test321"}
303];
304
305service = new LogglyService(configWithSerializer);
306```
307
308#### Custom implementation of service
309
310TODO
311
312## Development
313
314### Build and debugging
315
316In order to run full build of all bundles run:
317```
318npm run build
319```
320
321This script will create all types of build:
322* browser compressed
323* browser debugging
324* nodejs compressed (do we need it? :) )
325* nodejs debugging
326
327Also, you can run a specific build for each platform separately:
328```
329npm run build-prod-browser
330npm run build-prod-node
331npm run build-dev-browser
332npm run build-dev-node
333```
334
335For debugging purposes it should be convenient to use the watch mode:
336
337```
338npm run watch-prod-browser
339npm run watch-prod-node
340npm run watch-dev-browser
341npm run watch-dev-node
342```
343
344### Running tests
345
346In order to run unit tests run:
347
348```
349npm run test
350```
351
352In order to run unit tests with coverage run:
353
354```
355npm run coverage
356```
357
358It will build a beautiful code coverage report which you can check by running html file ```coverage/lcov-report/index.html```.
359
360### Deployment
361
362Please, find the ```.travis.yml``` file for the library lifecycle: install -> test -> build -> sonar analysis -> deploy.
363
364In order to deploy a new version, you need to run:
365
366```
367npx standard-version
368```
369
370This command bumps up the library version in all required files, builds the changelog and makes a new commit with a "version" tag. Using this tag travis will assemble and deploy the npm package.
371
372 **Please note**, that releasing happens only from master branch for each tagged commit.
373
374### Git workflow
375
376#### Commits
377
378Commits should follow the "conventional commit" agreement. It will be validated by Husky plugin on pre-commit git hook.
379
380#### Branches and pull requests
381
382Feel free to do anything you want in branches. All final commits should be rebased and clean. Please, create pull request for delivering your changes to master. All PR checks should be green. All sonar suggestions should be resolved and/or discussed if not applicable.
383
384## Thanks to
385
386creators of https://github.com/DxCx/ts-library-starter. Their repository was used as a start point for the library
387
\No newline at end of file