@extk/logger-cloudwatch 0.1.0
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.
- package/README.md +97 -0
- package/dist/index.d.mts +19 -0
- package/dist/index.d.ts +19 -0
- package/dist/index.js +116 -0
- package/dist/index.mjs +79 -0
- package/package.json +36 -0
package/README.md
ADDED
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
<p align="center">
|
|
2
|
+
<picture>
|
|
3
|
+
<source media="(prefers-color-scheme: dark)" srcset="https://img.shields.io/badge/extk%E2%9A%A1-expressive-blue?style=for-the-badge&labelColor=1a1a2e&color=4361ee">
|
|
4
|
+
<img alt="extk/expressive logo" src="https://img.shields.io/badge/extk%E2%9A%A1-expressive-blue?style=for-the-badge&labelColor=f0f0f0&color=4361ee">
|
|
5
|
+
</picture>
|
|
6
|
+
</p>
|
|
7
|
+
|
|
8
|
+
# @extk/logger-cloudwatch
|
|
9
|
+
|
|
10
|
+
Opinionated winston loggers with AWS CloudWatch support.
|
|
11
|
+
|
|
12
|
+
## Install
|
|
13
|
+
|
|
14
|
+
```sh
|
|
15
|
+
npm install @extk/logger-cloudwatch
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## Loggers
|
|
19
|
+
|
|
20
|
+
### `getCloudwatchLogger(opts)`
|
|
21
|
+
|
|
22
|
+
Streams JSON logs to AWS CloudWatch. Each process gets its own log stream named `YYYY-MM-DD/pid-<pid>`. Creates the log group if it doesn't exist.
|
|
23
|
+
|
|
24
|
+
```ts
|
|
25
|
+
import { getCloudwatchLogger } from '@extk/logger-cloudwatch';
|
|
26
|
+
|
|
27
|
+
const logger = getCloudwatchLogger({
|
|
28
|
+
aws: {
|
|
29
|
+
region: 'us-east-1',
|
|
30
|
+
logGroup: '/my-app/production',
|
|
31
|
+
credentials: {
|
|
32
|
+
accessKeyId: process.env.AWS_ACCESS_KEY_ID,
|
|
33
|
+
secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY,
|
|
34
|
+
},
|
|
35
|
+
},
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
logger.info('Request handled', { userId: 123 });
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
Optionally attach a context function to merge fields into every log entry:
|
|
42
|
+
|
|
43
|
+
```ts
|
|
44
|
+
const logger = getCloudwatchLogger({
|
|
45
|
+
aws: { ... },
|
|
46
|
+
contextFn: (info) => {
|
|
47
|
+
info['service'] = 'payments';
|
|
48
|
+
return info;
|
|
49
|
+
},
|
|
50
|
+
});
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
| Option | Description |
|
|
54
|
+
|-------------------|-------------|
|
|
55
|
+
| `aws.region` | AWS region |
|
|
56
|
+
| `aws.logGroup` | CloudWatch log group name |
|
|
57
|
+
| `aws.credentials` | `accessKeyId` + `secretAccessKey` |
|
|
58
|
+
| `contextFn` | Optional transform to add fields to every entry |
|
|
59
|
+
|
|
60
|
+
### `getConsoleLogger()`
|
|
61
|
+
|
|
62
|
+
Logs to stdout. Intended for development or simple services.
|
|
63
|
+
|
|
64
|
+
```ts
|
|
65
|
+
import { getConsoleLogger } from '@extk/logger-cloudwatch';
|
|
66
|
+
|
|
67
|
+
const logger = getConsoleLogger();
|
|
68
|
+
logger.info('Server started');
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### `getFileLogger(name?)`
|
|
72
|
+
|
|
73
|
+
Writes to `./logs/<name>.log`. Cached — calling with the same name returns the same instance.
|
|
74
|
+
|
|
75
|
+
```ts
|
|
76
|
+
import { getFileLogger } from '@extk/logger-cloudwatch';
|
|
77
|
+
|
|
78
|
+
const logger = getFileLogger('app');
|
|
79
|
+
logger.error(new Error('Something went wrong'));
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
| Option | Default |
|
|
83
|
+
|--------|---------|
|
|
84
|
+
| `name` | `'app'` |
|
|
85
|
+
| Output | `./logs/<name>.log` |
|
|
86
|
+
| Level | `debug` |
|
|
87
|
+
|
|
88
|
+
## Log format
|
|
89
|
+
|
|
90
|
+
Console and file loggers use a human-readable format:
|
|
91
|
+
|
|
92
|
+
```
|
|
93
|
+
DD/MM/YYYY HH:mm:ss[LEVEL]: message
|
|
94
|
+
DD/MM/YYYY HH:mm:ss[ERROR]: Error: something\n at ... ← stack trace for errors
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
CloudWatch receives structured JSON with `timestamp`, `level`, `message`, and any extra fields.
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import winston from 'winston';
|
|
2
|
+
|
|
3
|
+
declare const getFileLogger: (name?: string) => winston.Logger;
|
|
4
|
+
declare const getConsoleLogger: () => winston.Logger;
|
|
5
|
+
|
|
6
|
+
type options = {
|
|
7
|
+
aws: {
|
|
8
|
+
region: string;
|
|
9
|
+
logGroup: string;
|
|
10
|
+
credentials: {
|
|
11
|
+
accessKeyId: string;
|
|
12
|
+
secretAccessKey: string;
|
|
13
|
+
};
|
|
14
|
+
};
|
|
15
|
+
contextFn?: winston.Logform.TransformFunction;
|
|
16
|
+
};
|
|
17
|
+
declare const getCloudwatchLogger: (opts: options) => winston.Logger;
|
|
18
|
+
|
|
19
|
+
export { getCloudwatchLogger, getConsoleLogger, getFileLogger };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import winston from 'winston';
|
|
2
|
+
|
|
3
|
+
declare const getFileLogger: (name?: string) => winston.Logger;
|
|
4
|
+
declare const getConsoleLogger: () => winston.Logger;
|
|
5
|
+
|
|
6
|
+
type options = {
|
|
7
|
+
aws: {
|
|
8
|
+
region: string;
|
|
9
|
+
logGroup: string;
|
|
10
|
+
credentials: {
|
|
11
|
+
accessKeyId: string;
|
|
12
|
+
secretAccessKey: string;
|
|
13
|
+
};
|
|
14
|
+
};
|
|
15
|
+
contextFn?: winston.Logform.TransformFunction;
|
|
16
|
+
};
|
|
17
|
+
declare const getCloudwatchLogger: (opts: options) => winston.Logger;
|
|
18
|
+
|
|
19
|
+
export { getCloudwatchLogger, getConsoleLogger, getFileLogger };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
|
|
30
|
+
// src/index.ts
|
|
31
|
+
var index_exports = {};
|
|
32
|
+
__export(index_exports, {
|
|
33
|
+
getCloudwatchLogger: () => getCloudwatchLogger,
|
|
34
|
+
getConsoleLogger: () => getConsoleLogger,
|
|
35
|
+
getFileLogger: () => getFileLogger
|
|
36
|
+
});
|
|
37
|
+
module.exports = __toCommonJS(index_exports);
|
|
38
|
+
var import_winston3 = __toESM(require("winston"));
|
|
39
|
+
var import_winston_cloudwatch = __toESM(require("winston-cloudwatch"));
|
|
40
|
+
|
|
41
|
+
// ../../shared/src/loggers.ts
|
|
42
|
+
var import_winston2 = __toESM(require("winston"));
|
|
43
|
+
|
|
44
|
+
// ../../shared/src/common.ts
|
|
45
|
+
var import_winston = __toESM(require("winston"));
|
|
46
|
+
var defaultStringFormat = import_winston.default.format.combine(
|
|
47
|
+
import_winston.default.format.timestamp({ format: "DD/MM/YYYY HH:mm:ss" }),
|
|
48
|
+
import_winston.default.format.splat(),
|
|
49
|
+
import_winston.default.format.errors({ stack: true }),
|
|
50
|
+
import_winston.default.format.printf(({ level, message, timestamp, stack }) => `${timestamp}[${level.toUpperCase()}]: ${stack || message}`)
|
|
51
|
+
);
|
|
52
|
+
var consoleTransport = new import_winston.default.transports.Console({
|
|
53
|
+
handleExceptions: true
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
// ../../shared/src/loggers.ts
|
|
57
|
+
var createFileLogger = (filename) => import_winston2.default.createLogger({
|
|
58
|
+
format: defaultStringFormat,
|
|
59
|
+
transports: [
|
|
60
|
+
new import_winston2.default.transports.File({
|
|
61
|
+
filename: `./logs/${filename}.log`,
|
|
62
|
+
handleExceptions: true,
|
|
63
|
+
level: "debug"
|
|
64
|
+
})
|
|
65
|
+
]
|
|
66
|
+
});
|
|
67
|
+
var loggerRegistry = {};
|
|
68
|
+
var getFileLogger = (name = "app") => {
|
|
69
|
+
if (!loggerRegistry[name]) {
|
|
70
|
+
loggerRegistry[name] = createFileLogger(name.toString());
|
|
71
|
+
}
|
|
72
|
+
return loggerRegistry[name];
|
|
73
|
+
};
|
|
74
|
+
var consoleLogger;
|
|
75
|
+
var getConsoleLogger = () => {
|
|
76
|
+
if (!consoleLogger) {
|
|
77
|
+
consoleLogger = import_winston2.default.createLogger({
|
|
78
|
+
format: defaultStringFormat,
|
|
79
|
+
transports: [consoleTransport]
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
return consoleLogger;
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
// src/index.ts
|
|
86
|
+
var getCloudwatchLogger = (opts) => {
|
|
87
|
+
const formats = [
|
|
88
|
+
import_winston3.default.format.timestamp(),
|
|
89
|
+
import_winston3.default.format.splat(),
|
|
90
|
+
import_winston3.default.format.errors({ stack: true })
|
|
91
|
+
];
|
|
92
|
+
if (opts.contextFn) {
|
|
93
|
+
formats.push(import_winston3.default.format(opts.contextFn)());
|
|
94
|
+
}
|
|
95
|
+
return import_winston3.default.createLogger({
|
|
96
|
+
exitOnError: false,
|
|
97
|
+
format: import_winston3.default.format.combine(...formats),
|
|
98
|
+
transports: [
|
|
99
|
+
new import_winston_cloudwatch.default({
|
|
100
|
+
logGroupName: opts.aws.logGroup,
|
|
101
|
+
logStreamName: `${(/* @__PURE__ */ new Date()).toISOString().slice(0, 10)}/pid-${process.pid}`,
|
|
102
|
+
awsRegion: opts.aws.region,
|
|
103
|
+
awsAccessKeyId: opts.aws.credentials.accessKeyId,
|
|
104
|
+
awsSecretKey: opts.aws.credentials.secretAccessKey,
|
|
105
|
+
jsonMessage: true,
|
|
106
|
+
ensureLogGroup: true
|
|
107
|
+
})
|
|
108
|
+
]
|
|
109
|
+
});
|
|
110
|
+
};
|
|
111
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
112
|
+
0 && (module.exports = {
|
|
113
|
+
getCloudwatchLogger,
|
|
114
|
+
getConsoleLogger,
|
|
115
|
+
getFileLogger
|
|
116
|
+
});
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
// src/index.ts
|
|
2
|
+
import winston3 from "winston";
|
|
3
|
+
import WinstonCloudWatch from "winston-cloudwatch";
|
|
4
|
+
|
|
5
|
+
// ../../shared/src/loggers.ts
|
|
6
|
+
import winston2 from "winston";
|
|
7
|
+
|
|
8
|
+
// ../../shared/src/common.ts
|
|
9
|
+
import winston from "winston";
|
|
10
|
+
var defaultStringFormat = winston.format.combine(
|
|
11
|
+
winston.format.timestamp({ format: "DD/MM/YYYY HH:mm:ss" }),
|
|
12
|
+
winston.format.splat(),
|
|
13
|
+
winston.format.errors({ stack: true }),
|
|
14
|
+
winston.format.printf(({ level, message, timestamp, stack }) => `${timestamp}[${level.toUpperCase()}]: ${stack || message}`)
|
|
15
|
+
);
|
|
16
|
+
var consoleTransport = new winston.transports.Console({
|
|
17
|
+
handleExceptions: true
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
// ../../shared/src/loggers.ts
|
|
21
|
+
var createFileLogger = (filename) => winston2.createLogger({
|
|
22
|
+
format: defaultStringFormat,
|
|
23
|
+
transports: [
|
|
24
|
+
new winston2.transports.File({
|
|
25
|
+
filename: `./logs/${filename}.log`,
|
|
26
|
+
handleExceptions: true,
|
|
27
|
+
level: "debug"
|
|
28
|
+
})
|
|
29
|
+
]
|
|
30
|
+
});
|
|
31
|
+
var loggerRegistry = {};
|
|
32
|
+
var getFileLogger = (name = "app") => {
|
|
33
|
+
if (!loggerRegistry[name]) {
|
|
34
|
+
loggerRegistry[name] = createFileLogger(name.toString());
|
|
35
|
+
}
|
|
36
|
+
return loggerRegistry[name];
|
|
37
|
+
};
|
|
38
|
+
var consoleLogger;
|
|
39
|
+
var getConsoleLogger = () => {
|
|
40
|
+
if (!consoleLogger) {
|
|
41
|
+
consoleLogger = winston2.createLogger({
|
|
42
|
+
format: defaultStringFormat,
|
|
43
|
+
transports: [consoleTransport]
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
return consoleLogger;
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
// src/index.ts
|
|
50
|
+
var getCloudwatchLogger = (opts) => {
|
|
51
|
+
const formats = [
|
|
52
|
+
winston3.format.timestamp(),
|
|
53
|
+
winston3.format.splat(),
|
|
54
|
+
winston3.format.errors({ stack: true })
|
|
55
|
+
];
|
|
56
|
+
if (opts.contextFn) {
|
|
57
|
+
formats.push(winston3.format(opts.contextFn)());
|
|
58
|
+
}
|
|
59
|
+
return winston3.createLogger({
|
|
60
|
+
exitOnError: false,
|
|
61
|
+
format: winston3.format.combine(...formats),
|
|
62
|
+
transports: [
|
|
63
|
+
new WinstonCloudWatch({
|
|
64
|
+
logGroupName: opts.aws.logGroup,
|
|
65
|
+
logStreamName: `${(/* @__PURE__ */ new Date()).toISOString().slice(0, 10)}/pid-${process.pid}`,
|
|
66
|
+
awsRegion: opts.aws.region,
|
|
67
|
+
awsAccessKeyId: opts.aws.credentials.accessKeyId,
|
|
68
|
+
awsSecretKey: opts.aws.credentials.secretAccessKey,
|
|
69
|
+
jsonMessage: true,
|
|
70
|
+
ensureLogGroup: true
|
|
71
|
+
})
|
|
72
|
+
]
|
|
73
|
+
});
|
|
74
|
+
};
|
|
75
|
+
export {
|
|
76
|
+
getCloudwatchLogger,
|
|
77
|
+
getConsoleLogger,
|
|
78
|
+
getFileLogger
|
|
79
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@extk/logger-cloudwatch",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"type": "commonjs",
|
|
5
|
+
"publishConfig": {
|
|
6
|
+
"access": "public"
|
|
7
|
+
},
|
|
8
|
+
"files": [
|
|
9
|
+
"dist"
|
|
10
|
+
],
|
|
11
|
+
"exports": {
|
|
12
|
+
".": {
|
|
13
|
+
"types": "./dist/index.d.ts",
|
|
14
|
+
"import": "./dist/index.mjs",
|
|
15
|
+
"require": "./dist/index.js"
|
|
16
|
+
}
|
|
17
|
+
},
|
|
18
|
+
"engines": {
|
|
19
|
+
"node": ">=22.0.0"
|
|
20
|
+
},
|
|
21
|
+
"scripts": {
|
|
22
|
+
"build": "tsup",
|
|
23
|
+
"prepublishOnly": "npm run build"
|
|
24
|
+
},
|
|
25
|
+
"dependencies": {
|
|
26
|
+
"winston": "^3.11.0",
|
|
27
|
+
"winston-cloudwatch": "^6.3.0"
|
|
28
|
+
},
|
|
29
|
+
"license": "ISC",
|
|
30
|
+
"description": "AWS CloudWatch logger",
|
|
31
|
+
"repository": {
|
|
32
|
+
"type": "git",
|
|
33
|
+
"url": "https://github.com/sergeytangyan/extk-logger",
|
|
34
|
+
"directory": "packages/cloudwatch"
|
|
35
|
+
}
|
|
36
|
+
}
|