Skip to content

Commit b3b3f3f

Browse files
committed
feat(extension-logging): add http access and method invocation logging
- add architecture diagram and examples to README - improve naming and exporting - configure the http access logger for REST routes only
1 parent bb10285 commit b3b3f3f

File tree

21 files changed

+736
-671
lines changed

21 files changed

+736
-671
lines changed

CODEOWNERS

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ packages/testlab/* @bajtos
3535
packages/tsdocs/* @raymondfeng
3636

3737
extensions/health/* @raymondfeng
38+
extensions/logging/* @raymondfeng
39+
extensions/metrics/* @raymondfeng
3840

3941
examples/todo/* @bajtos @hacksparrow
4042
examples/context/* @raymondfeng

acceptance/extension-logging-fluentd/package-lock.json

Lines changed: 27 additions & 29 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

acceptance/extension-logging-fluentd/src/__tests__/accpetance/fluent.acceptance.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,8 +57,8 @@ describe('LoggingComponent', () => {
5757
async function givenAppWithCustomConfig() {
5858
app = givenApplication();
5959
app.configure(LoggingBindings.FLUENT_SENDER).to({
60-
host: process.env.FLUENTD_SERVICE_HOST || '127.0.0.1',
61-
port: +(process.env.FLUENTD_SERVICE_PORT_TCP || 0) || 24224,
60+
host: process.env.FLUENTD_SERVICE_HOST ?? '127.0.0.1',
61+
port: +(process.env.FLUENTD_SERVICE_PORT_TCP ?? 24224),
6262
timeout: 3.0,
6363
reconnectInterval: 600000, // 10 minutes
6464
});

acceptance/extension-logging-fluentd/src/__tests__/fixtures/fluentd.docker.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ import {GenericContainer, StartedTestContainer} from 'testcontainers';
1010
export const ROOT_DIR = path.join(__dirname, '../../../fixtures');
1111
export const ETC_DIR = path.join(ROOT_DIR, 'etc');
1212

13-
/* eslint-disable require-atomic-updates */
1413
async function startFluentd() {
1514
if (process.env.FLUENTD_SERVICE_HOST != null) return;
1615
const container = await new GenericContainer(

docs/site/MONOREPO.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,9 @@ The [loopback-next](https://github.com/strongloop/loopback-next) repository uses
3030
| [example-soap-calculator](https://github.com/strongloop/loopback-next/tree/master/examples/soap-calculator) | @loopback/example-soap-calculator | A tutorial demonstrating integration with a SOAP webservice |
3131
| [example-todo-list](https://github.com/strongloop/loopback-next/tree/master/examples/todo-list) | @loopback/example-todo-list | Continuation of the todo example using relations in LoopBack 4 |
3232
| [example-todo](https://github.com/strongloop/loopback-next/tree/master/examples/todo) | @loopback/example-todo | A basic tutorial for getting started with Loopback 4 |
33+
| [extension-health](https://github.com/strongloop/loopback-next/tree/master/extensions/health) | @loopback/extension-health | Expose health check related endpoints |
34+
| [extension-logging](https://github.com/strongloop/loopback-next/tree/master/extensions/logging) | @loopback/extension-logging | Add Winston Logger and Fluentd integration |
35+
| [extension-metrics](https://github.com/strongloop/loopback-next/tree/master/extensions/metrics) | @loopback/extension-metrics | Report metrics to Prometheus |
3336
| [http-caching-proxy](https://github.com/strongloop/loopback-next/tree/master/packages/http-caching-proxy) | @loopback/http-caching-proxy | A caching HTTP proxy for integration tests. NOT SUITABLE FOR PRODUCTION USE! |
3437
| [http-server](https://github.com/strongloop/loopback-next/tree/master/packages/http-server) | @loopback/http-server | A wrapper for creating HTTP/HTTPS servers |
3538
| [metadata](https://github.com/strongloop/loopback-next/tree/master/packages/metadata) | @loopback/metadata | Utilities to help developers implement TypeScript decorators, define/merge metadata, and inspect metadata |
@@ -44,7 +47,6 @@ The [loopback-next](https://github.com/strongloop/loopback-next) repository uses
4447
| [service-proxy](https://github.com/strongloop/loopback-next/tree/master/packages/service-proxy) | @loopback/service-proxy | A common set of interfaces for interacting with service oriented backends such as REST APIs, SOAP Web Services, and gRPC microservices |
4548
| [testlab](https://github.com/strongloop/loopback-next/tree/master/packages/testlab) | @loopback/testlab | A collection of test utilities we use to write LoopBack tests |
4649
| [tsdocs](https://github.com/strongloop/loopback-next/tree/master/packages/tsdocs) | @loopback/tsdocs | An internal package to generate api docs using Microsoft api-extractor and api-documenter |
47-
| [extensions/health](https://github.com/strongloop/loopback-next/tree/master/extensions/health) | @loopback/extension-health | Expose health check related endpoints |
4850

4951
We use npm scripts declared in
5052
[package.json](https://github.com/strongloop/loopback-next/blob/master/package.json)

extensions/logging/README.md

Lines changed: 95 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@ This module contains a component provides logging facilities based on
1111
> using `0.x.y` versions. Their APIs and functionality may be subject to
1212
> breaking changes in future releases.
1313
14+
## Architecture overview
15+
16+
![logging-component](logging-component.png)
17+
1418
## Installation
1519

1620
```sh
@@ -34,21 +38,71 @@ In the constructor, add the component to your application:
3438
this.component(LoggingComponent);
3539
```
3640

37-
The component contributes bindings with keys listed below:
41+
Now your application can add a controller as follows to leverage the logging
42+
facilities:
43+
44+
```ts
45+
import {inject} from '@loopback/context';
46+
import {Logger, logInvocation} from '@loopback/extension-logging';
47+
import {get, param} from '@loopback/rest';
48+
49+
class MyController {
50+
// Inject a winston logger
51+
@inject(LoggingBindings.WINSTON_LOGGER)
52+
private logger: Logger;
53+
54+
// http access is logged by a global interceptor
55+
@get('/greet/{name}')
56+
// log the `greet` method invocations
57+
@logInvocation()
58+
greet(@param.path.string('name') name: string) {
59+
return `Hello, ${name}`;
60+
}
61+
62+
@get('/hello/{name}')
63+
hello(@param.path.string('name') name: string) {
64+
// Use the winston logger explicitly
65+
this.logger.log('info', `greeting ${name}`);
66+
return `Hello, ${name}`;
67+
}
68+
}
69+
```
70+
71+
## Configure the logging component
72+
73+
The logging component can be configured as follows:
74+
75+
```ts
76+
app.configure(LoggingBindings.COMPONENT).to({
77+
enableFluent: false, // default to true
78+
enableHttpAccessLog: true, // default to true
79+
});
80+
```
81+
82+
- `enableFluent`: Enable logs to be sent to Fluentd
83+
- `enableHttpAccessLog`: Enable all http requests to be logged via a global
84+
interceptor
85+
86+
The component contributes bindings with keys declared under `LoggingBindings`
87+
namespace as follows:
3888

39-
- LoggingBindings.FLUENT_SENDER - A fluent sender
40-
- LoggingBindings.WINSTON_LOGGER - A winston logger
41-
- LoggingBindings.WINSTON_TRANSPORT_FLUENT - A fluent transport for winston
89+
- FLUENT_SENDER - A fluent sender
90+
- WINSTON_LOGGER - A winston logger
91+
- WINSTON_TRANSPORT_FLUENT - A fluent transport for winston
92+
- WINSTON_INTERCEPTOR - A local interceptor set by `@logInvocation` to log
93+
method invocations
94+
- WINSTON_HTTP_ACCESS_LOGGER - A global interceptor that logs http access with
95+
[Morgan](https://github.com/expressjs/morgan) format
4296

4397
The fluent sender and transport for winston can be configured against
44-
`LoggingBindings.FLUENT_SENDER`:
98+
`FLUENT_SENDER`:
4599

46100
```ts
47101
import {LoggingBindings} from '@loopback/extension-logging';
48102

49103
app.configure(LoggingBindings.FLUENT_SENDER).to({
50-
host: process.env.FLUENTD_SERVICE_HOST || 'localhost',
51-
port: +(process.env.FLUENTD_SERVICE_PORT_TCP || 0) || 24224,
104+
host: process.env.FLUENTD_SERVICE_HOST ?? 'localhost',
105+
port: +(process.env.FLUENTD_SERVICE_PORT_TCP ?? 24224),
52106
timeout: 3.0,
53107
reconnectInterval: 600000, // 10 minutes
54108
});
@@ -75,9 +129,17 @@ points:
75129
```ts
76130
import {extensionFor} from '@loopback/core';
77131
import {format} from 'winston';
78-
import {WINSTON_FORMAT, WINSTON_TRANSPORT} from '@loopback/extension-logging';
79-
80-
const myFormat: Format = ...;
132+
import {
133+
WINSTON_FORMAT,
134+
WINSTON_TRANSPORT,
135+
WinstonFormat,
136+
WinstonTransports,
137+
} from '@loopback/extension-logging';
138+
139+
const myFormat: WinstonFormat = format((info, opts) => {
140+
console.log(info);
141+
return false;
142+
})();
81143

82144
ctx
83145
.bind('logging.winston.formats.myFormat')
@@ -87,6 +149,29 @@ ctx
87149
.bind('logging.winston.formats.colorize')
88150
.to(format.colorize())
89151
.apply(extensionFor(WINSTON_FORMAT));
152+
153+
const consoleTransport = new WinstonTransports.Console({
154+
level: 'info',
155+
format: format.combine(format.colorize(), format.simple()),
156+
});
157+
ctx
158+
.bind('logging.winston.transports.console')
159+
.to(consoleTransport)
160+
.apply(extensionFor(WINSTON_TRANSPORT));
161+
```
162+
163+
If no transport is contributed, the winston logger uses the
164+
[console transport](https://github.com/winstonjs/winston/blob/master/docs/transports.md#console-transport).
165+
166+
No default format is configured for the winston logger.
167+
168+
The access log interceptor can also be configured to customize
169+
[Morgan format and options](https://github.com/expressjs/morgan#morganformat-options):
170+
171+
```ts
172+
ctx
173+
.configure(LoggingBindings.WINSTON_HTTP_ACCESS_LOGGER)
174+
.to({format: 'combined'});
90175
```
91176

92177
## Contributions
339 KB
Loading

0 commit comments

Comments
 (0)