@logtail/pino 0.0.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.
package/LICENSE.md ADDED
@@ -0,0 +1,7 @@
1
+ # ISC License
2
+
3
+ Copyright (c) 2023, Better Stack, Inc.
4
+
5
+ Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies.
6
+
7
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,20 @@
1
+ # [Logtail](https://betterstack.com/logtail) JavaScript Pino transport by [Better Stack](https://betterstack.com/)
2
+
3
+ [![Logtail dashboard](https://user-images.githubusercontent.com/19272921/154085622-59997d5a-3f91-4bc9-a815-3b8ead16d28d.jpeg)](https://betterstack.com/logtail)
4
+
5
+
6
+ [![ISC License](https://img.shields.io/badge/license-ISC-ff69b4.svg)](LICENSE.md)
7
+ [![npm @logtail/pino](https://img.shields.io/npm/v/@logtail/pino?color=success&label=npm%20%40logtail%2Fpino)](https://www.npmjs.com/package/@logtail/pino)
8
+
9
+ Experience SQL-compatible structured log management based on ClickHouse. [Learn more ↗](https://logtail.com/)
10
+
11
+ ## Documentation
12
+
13
+ [Getting started ↗](https://betterstack.com/docs/logs/javascript)
14
+
15
+ ## Need help?
16
+ Please let us know at [hello@beterstack.com](mailto:hello@beterstack.com). We're happy to help!
17
+
18
+ ---
19
+
20
+ [ISC license](LICENSE.md), [contributing guidelines](../../CONTRIBUTING.md).
@@ -0,0 +1,6 @@
1
+ import { LogLevel } from "@logtail/types";
2
+ /**
3
+ * Return a Logtail `LogLevel` based on the Pino level
4
+ * @param level number - Pino log level
5
+ */
6
+ export declare function getLogLevel(level: number): LogLevel;
@@ -0,0 +1,31 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getLogLevel = void 0;
4
+ const types_1 = require("@logtail/types");
5
+ /**
6
+ * Return a Logtail `LogLevel` based on the Pino level
7
+ * @param level number - Pino log level
8
+ */
9
+ function getLogLevel(level) {
10
+ // TODO: Trace 10
11
+ if (level <= 10) {
12
+ return types_1.LogLevel.Debug;
13
+ }
14
+ // Debug
15
+ if (level <= 20) {
16
+ return types_1.LogLevel.Debug;
17
+ }
18
+ // Info
19
+ if (level <= 30) {
20
+ return types_1.LogLevel.Info;
21
+ }
22
+ // Warn
23
+ if (level <= 40) {
24
+ return types_1.LogLevel.Warn;
25
+ }
26
+ // Everything above this level is considered an error
27
+ // TODO: Fatal 60 (Error 50)
28
+ return types_1.LogLevel.Error;
29
+ }
30
+ exports.getLogLevel = getLogLevel;
31
+ //# sourceMappingURL=helpers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"helpers.js","sourceRoot":"","sources":["../../src/helpers.ts"],"names":[],"mappings":";;;AAAA,0CAA0C;AAE1C;;;GAGG;AACH,SAAgB,WAAW,CAAC,KAAa;IAEvC,iBAAiB;IACjB,IAAI,KAAK,IAAI,EAAE,EAAE;QACf,OAAO,gBAAQ,CAAC,KAAK,CAAC;KACvB;IAED,QAAQ;IACR,IAAI,KAAK,IAAI,EAAE,EAAE;QACf,OAAO,gBAAQ,CAAC,KAAK,CAAC;KACvB;IAED,OAAO;IACP,IAAI,KAAK,IAAI,EAAE,EAAE;QACf,OAAO,gBAAQ,CAAC,IAAI,CAAC;KACtB;IAED,OAAO;IACP,IAAI,KAAK,IAAI,EAAE,EAAE;QACf,OAAO,gBAAQ,CAAC,IAAI,CAAC;KACtB;IAED,qDAAqD;IACrD,4BAA4B;IAC5B,OAAO,gBAAQ,CAAC,KAAK,CAAC;AACxB,CAAC;AAzBD,kCAyBC"}
@@ -0,0 +1,2 @@
1
+ import { logtailTransport } from "./pino";
2
+ export default logtailTransport;
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const pino_1 = require("./pino");
4
+ exports.default = pino_1.logtailTransport;
5
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";;AAAA,iCAA0C;AAE1C,kBAAe,uBAAgB,CAAA"}
@@ -0,0 +1,3 @@
1
+ /// <reference types="node" />
2
+ import { PinoLokiOptionsContract } from './Contracts';
3
+ export default function (options: PinoLokiOptionsContract): Promise<import("stream").Transform & import("pino-abstract-transport").OnUnknown>;
@@ -0,0 +1,62 @@
1
+ "use strict";
2
+ var __asyncValues = (this && this.__asyncValues) || function (o) {
3
+ if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
4
+ var m = o[Symbol.asyncIterator], i;
5
+ return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i);
6
+ function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }
7
+ function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }
8
+ };
9
+ var __importDefault = (this && this.__importDefault) || function (mod) {
10
+ return (mod && mod.__esModule) ? mod : { "default": mod };
11
+ };
12
+ Object.defineProperty(exports, "__esModule", { value: true });
13
+ const pino_abstract_transport_1 = __importDefault(require("pino-abstract-transport"));
14
+ const LogPusher_1 = require("./LogPusher");
15
+ async function default_1(options) {
16
+ var _a, _b, _c, _d, _e, _f;
17
+ (_a = options.timeout) !== null && _a !== void 0 ? _a : ;
18
+ 30000;
19
+ (_b = options.silenceErrors) !== null && _b !== void 0 ? _b : ;
20
+ false;
21
+ (_c = options.batching) !== null && _c !== void 0 ? _c : ;
22
+ true;
23
+ (_d = options.interval) !== null && _d !== void 0 ? _d : ;
24
+ 5;
25
+ (_e = options.replaceTimestamp) !== null && _e !== void 0 ? _e : ;
26
+ false;
27
+ (_f = options.propsToLabels) !== null && _f !== void 0 ? _f : ;
28
+ [];
29
+ const logPusher = new LogPusher_1.LogPusher(options);
30
+ return pino_abstract_transport_1.default(async (source) => {
31
+ var e_1, _a;
32
+ let pinoLogBuffer = [];
33
+ if (options.batching) {
34
+ setInterval(async () => {
35
+ if (pinoLogBuffer.length === 0) {
36
+ return;
37
+ }
38
+ logPusher.push(pinoLogBuffer);
39
+ pinoLogBuffer = [];
40
+ }, options.interval * 1000);
41
+ }
42
+ try {
43
+ for (var source_1 = __asyncValues(source), source_1_1; source_1_1 = await source_1.next(), !source_1_1.done;) {
44
+ let obj = source_1_1.value;
45
+ if (options.batching) {
46
+ pinoLogBuffer.push(obj);
47
+ continue;
48
+ }
49
+ logPusher.push(obj);
50
+ }
51
+ }
52
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
53
+ finally {
54
+ try {
55
+ if (source_1_1 && !source_1_1.done && (_a = source_1.return)) await _a.call(source_1);
56
+ }
57
+ finally { if (e_1) throw e_1.error; }
58
+ }
59
+ });
60
+ }
61
+ exports.default = default_1;
62
+ //# sourceMappingURL=pino-loki-index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pino-loki-index.js","sourceRoot":"","sources":["../../src/pino-loki-index.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,sFAA2C;AAE3C,2CAAuC;AAExB,KAAK,oBAAW,OAAgC;;IAC7D,MAAA,OAAO,CAAC,OAAO,mCAAG,CAAA;IAAE,KAAK,CAAA;IACzB,MAAA,OAAO,CAAC,aAAa,mCAAG,CAAA;IAAE,KAAK,CAAA;IAC/B,MAAA,OAAO,CAAC,QAAQ,mCAAG,CAAA;IAAE,IAAI,CAAA;IACzB,MAAA,OAAO,CAAC,QAAQ,mCAAG,CAAA;IAAE,CAAC,CAAA;IACtB,MAAA,OAAO,CAAC,gBAAgB,mCAAG,CAAA;IAAE,KAAK,CAAA;IAClC,MAAA,OAAO,CAAC,aAAa,mCAAG,CAAA;IAAE,EAAE,CAAA;IAC5B,MAAM,SAAS,GAAG,IAAI,qBAAS,CAAC,OAAO,CAAC,CAAA;IAExC,OAAO,iCAAK,CAAC,KAAK,EAAE,MAAW,EAAE,EAAE;;QACjC,IAAI,aAAa,GAAc,EAAE,CAAA;QAEjC,IAAI,OAAO,CAAC,QAAQ,EAAE;YACpB,WAAW,CAAC,KAAK,IAAI,EAAE;gBACrB,IAAI,aAAa,CAAC,MAAM,KAAK,CAAC,EAAE;oBAC9B,OAAM;iBACP;gBAED,SAAS,CAAC,IAAI,CAAC,aAAa,CAAC,CAAA;gBAC7B,aAAa,GAAG,EAAE,CAAA;YACpB,CAAC,EAAE,OAAO,CAAC,QAAS,GAAG,IAAI,CAAC,CAAA;SAC7B;;YAED,KAAsB,IAAA,WAAA,cAAA,MAAM,CAAA,YAAA;gBAAjB,IAAI,GAAG,mBAAA,CAAA;gBAChB,IAAI,OAAO,CAAC,QAAQ,EAAE;oBACpB,aAAa,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;oBACvB,SAAQ;iBACT;gBAED,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;aACpB;;;;;;;;;IACH,CAAC,CAAC,CAAA;AACJ,CAAC;AAhCD,4BAgCC"}
@@ -0,0 +1,11 @@
1
+ /// <reference types="node" />
2
+ import { ILogtailOptions } from "@logtail/types";
3
+ export interface PinoLog {
4
+ level: number;
5
+ [key: string]: any;
6
+ }
7
+ export interface IPinoLogtailOptions {
8
+ sourceToken: string;
9
+ options: Partial<ILogtailOptions>;
10
+ }
11
+ export declare function logtailTransport(options: IPinoLogtailOptions): Promise<import("stream").Transform & import("pino-abstract-transport").OnUnknown>;
@@ -0,0 +1,66 @@
1
+ "use strict";
2
+ var __asyncValues = (this && this.__asyncValues) || function (o) {
3
+ if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
4
+ var m = o[Symbol.asyncIterator], i;
5
+ return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i);
6
+ function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }
7
+ function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }
8
+ };
9
+ var __importDefault = (this && this.__importDefault) || function (mod) {
10
+ return (mod && mod.__esModule) ? mod : { "default": mod };
11
+ };
12
+ Object.defineProperty(exports, "__esModule", { value: true });
13
+ exports.logtailTransport = void 0;
14
+ const pino_abstract_transport_1 = __importDefault(require("pino-abstract-transport"));
15
+ const node_1 = require("@logtail/node");
16
+ const helpers_1 = require("./helpers");
17
+ async function logtailTransport(options) {
18
+ // FIXME: error handling for no source token
19
+ const logtail = new node_1.Logtail(options.sourceToken);
20
+ return pino_abstract_transport_1.default(async (source) => {
21
+ var e_1, _a;
22
+ try {
23
+ for (var source_1 = __asyncValues(source), source_1_1; source_1_1 = await source_1.next(), !source_1_1.done;) {
24
+ let obj = source_1_1.value;
25
+ // Log should have string `msg` key, > 0 length
26
+ if (typeof obj.msg !== "string" || !obj.msg.length) {
27
+ console.error('Field "msg" has to be a non-empty string.');
28
+ continue;
29
+ }
30
+ // Logging meta data
31
+ const meta = {};
32
+ // Copy `time` if set
33
+ if (typeof obj.time === "string" || obj.time.length) {
34
+ const time = new Date(obj.time);
35
+ if (!isNaN(time.valueOf())) {
36
+ meta.dt = time;
37
+ }
38
+ }
39
+ // Carry over any additional data fields
40
+ Object.keys(obj)
41
+ .filter(key => ["time", "msg", "level", "v"].indexOf(key) < 0)
42
+ .forEach(key => (meta[key] = obj[key]));
43
+ // Determine the log level
44
+ let level;
45
+ try {
46
+ level = helpers_1.getLogLevel(obj.level);
47
+ }
48
+ catch (_) {
49
+ console.error('Error while mapping log level.');
50
+ continue;
51
+ }
52
+ // Log to Logtail
53
+ logtail.log(obj.msg, level, meta);
54
+ }
55
+ }
56
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
57
+ finally {
58
+ try {
59
+ if (source_1_1 && !source_1_1.done && (_a = source_1.return)) await _a.call(source_1);
60
+ }
61
+ finally { if (e_1) throw e_1.error; }
62
+ }
63
+ });
64
+ }
65
+ exports.logtailTransport = logtailTransport;
66
+ //# sourceMappingURL=pino.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pino.js","sourceRoot":"","sources":["../../src/pino.ts"],"names":[],"mappings":";;;;;;;;;;;;;AAAA,sFAA2C;AAE3C,wCAAwC;AAGxC,uCAAwC;AAiBjC,KAAK,UAAU,gBAAgB,CAAC,OAA4B;IACjE,6CAA6C;IAC7C,MAAM,OAAO,GAAG,IAAI,cAAO,CAAC,OAAO,CAAC,WAAW,CAAC,CAAA;IAEhD,OAAO,iCAAK,CAAC,KAAK,EAAE,MAAW,EAAE,EAAE;;;YACjC,KAAsB,IAAA,WAAA,cAAA,MAAM,CAAA,YAAA;gBAAjB,IAAI,GAAG,mBAAA,CAAA;gBAChB,+CAA+C;gBAC/C,IAAI,OAAO,GAAG,CAAC,GAAG,KAAK,QAAQ,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,EAAE;oBAClD,OAAO,CAAC,KAAK,CAAC,2CAA2C,CAAC,CAAA;oBAC1D,SAAQ;iBACT;gBAED,oBAAoB;gBACpB,MAAM,IAAI,GAAY,EAAE,CAAC;gBAEzB,qBAAqB;gBACrB,IAAI,OAAO,GAAG,CAAC,IAAI,KAAK,QAAQ,IAAI,GAAG,CAAC,IAAI,CAAC,MAAM,EAAE;oBACnD,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;oBAChC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,EAAE;wBAC1B,IAAI,CAAC,EAAE,GAAG,IAAI,CAAC;qBAChB;iBACF;gBAED,wCAAwC;gBACxC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC;qBACb,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;qBAC7D,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;gBAE1C,0BAA0B;gBAC1B,IAAI,KAAe,CAAC;gBAEpB,IAAI;oBACF,KAAK,GAAG,qBAAW,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;iBAChC;gBAAC,OAAO,CAAC,EAAE;oBACV,OAAO,CAAC,KAAK,CAAC,gCAAgC,CAAC,CAAA;oBAC/C,SAAQ;iBACT;gBAED,iBAAiB;gBACjB,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC;aACnC;;;;;;;;;IACH,CAAC,CAAC,CAAA;AACJ,CAAC;AA1CD,4CA0CC"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,117 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const pino_1 = __importDefault(require("pino"));
7
+ const node_1 = require("@logtail/node");
8
+ const types_1 = require("@logtail/types");
9
+ // Numeric log level test type
10
+ // type LevelTest = [number, LogLevel, LogLevelString];
11
+ // Sample log message
12
+ const message = "Something to do with something";
13
+ /**
14
+ * Create a Pino logger instance with Logtail transport
15
+ *
16
+ */
17
+ function createLogger() {
18
+ const token = "invalid source token";
19
+ const logtailOptions = { ignoreExceptions: true };
20
+ const options = { sourceToken: token, options: logtailOptions };
21
+ const transport = pino_1.default.transport({
22
+ target: "./pino.js",
23
+ options: options
24
+ });
25
+ return pino_1.default(transport);
26
+ }
27
+ /**
28
+ * Test a Bunyan log level vs. a Logtail `LogLevel`
29
+ *
30
+ * @param level LogLevelString - Bunyan log level (string)
31
+ * @param logLevel LogLevel - Logtail log level
32
+ * @param cb Function - Callback to execute to signal test completion
33
+ */
34
+ async function testLevel(level, logLevel, cb) {
35
+ // Logtail fixtures
36
+ const logtail = new node_1.Logtail("test", { batchInterval: 1 });
37
+ logtail.setSync(async (logs) => {
38
+ // Should be exactly one log
39
+ expect(logs.length).toBe(1);
40
+ // Message should match
41
+ expect(logs[0].message).toBe(message);
42
+ // Log level should be 'info'
43
+ expect(logs[0].level).toBe(logLevel);
44
+ // Signal that the test has finished
45
+ setImmediate(() => cb());
46
+ return logs;
47
+ });
48
+ // Create Bunyan logger
49
+ const logger = createLogger(logtail);
50
+ // Log out to Bunyan
51
+ logger[level](message);
52
+ }
53
+ describe("Bunyan tests", () => {
54
+ it("should log at the 'debug' level", async (done) => {
55
+ return testLevel("debug", types_1.LogLevel.Debug, done);
56
+ });
57
+ it("should log at the 'info' level", async (done) => {
58
+ return testLevel("info", types_1.LogLevel.Info, done);
59
+ });
60
+ it("should log at the 'warn' level", async (done) => {
61
+ return testLevel("warn", types_1.LogLevel.Warn, done);
62
+ });
63
+ it("should log at the 'error' level", async (done) => {
64
+ return testLevel("error", types_1.LogLevel.Error, done);
65
+ });
66
+ it("should log at the 'fatal' level", async (done) => {
67
+ return testLevel("fatal", types_1.LogLevel.Error, done);
68
+ });
69
+ it("should log using number levels", async (done) => {
70
+ // Fixtures
71
+ const levels = [
72
+ [25, types_1.LogLevel.Debug, "debug"],
73
+ [35, types_1.LogLevel.Info, "info"],
74
+ [45, types_1.LogLevel.Warn, "warn"],
75
+ [55, types_1.LogLevel.Error, "error"]
76
+ ];
77
+ const logtail = new node_1.Logtail("test", {
78
+ batchInterval: 1000,
79
+ batchSize: levels.length
80
+ });
81
+ logtail.setSync(async (logs) => {
82
+ expect(logs.length).toBe(levels.length);
83
+ done();
84
+ return logs;
85
+ });
86
+ // Create Bunyan logger
87
+ const logger = createLogger(logtail);
88
+ // Cycle through levels, and log
89
+ levels.forEach(level => logger[level[2]](message));
90
+ });
91
+ it("should include arbitrary extra data fields", async (done) => {
92
+ const logtail = new node_1.Logtail("test");
93
+ logtail.setSync(async (logs) => {
94
+ expect(logs).toHaveLength(1);
95
+ expect(logs[0].message).toEqual("i am the message");
96
+ expect(logs[0].foo).toEqual("bar");
97
+ expect(logs[0].some).toEqual({ nested: "stuff" });
98
+ done();
99
+ return logs;
100
+ });
101
+ const logger = createLogger(logtail);
102
+ logger.info({ foo: "bar", some: { nested: "stuff" } }, "i am the message");
103
+ });
104
+ it("should include correct context fields", async (done) => {
105
+ const logtail = new node_1.Logtail("test");
106
+ logtail.setSync(async (logs) => {
107
+ const context = logs[0].context;
108
+ const runtime = context.runtime;
109
+ expect(runtime.file).toEqual("bunyan.test.ts");
110
+ done();
111
+ return logs;
112
+ });
113
+ const logger = createLogger(logtail);
114
+ logger.info("message with context");
115
+ });
116
+ });
117
+ //# sourceMappingURL=pino.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pino.test.js","sourceRoot":"","sources":["../../src/pino.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import { LogLevel } from "@logtail/types";
2
+ /**
3
+ * Return a Logtail `LogLevel` based on the Pino level
4
+ * @param level number - Pino log level
5
+ */
6
+ export declare function getLogLevel(level: number): LogLevel;
@@ -0,0 +1,27 @@
1
+ import { LogLevel } from "@logtail/types";
2
+ /**
3
+ * Return a Logtail `LogLevel` based on the Pino level
4
+ * @param level number - Pino log level
5
+ */
6
+ export function getLogLevel(level) {
7
+ // TODO: Trace 10
8
+ if (level <= 10) {
9
+ return LogLevel.Debug;
10
+ }
11
+ // Debug
12
+ if (level <= 20) {
13
+ return LogLevel.Debug;
14
+ }
15
+ // Info
16
+ if (level <= 30) {
17
+ return LogLevel.Info;
18
+ }
19
+ // Warn
20
+ if (level <= 40) {
21
+ return LogLevel.Warn;
22
+ }
23
+ // Everything above this level is considered an error
24
+ // TODO: Fatal 60 (Error 50)
25
+ return LogLevel.Error;
26
+ }
27
+ //# sourceMappingURL=helpers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"helpers.js","sourceRoot":"","sources":["../../src/helpers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAE1C;;;GAGG;AACH,MAAM,UAAU,WAAW,CAAC,KAAa;IAEvC,iBAAiB;IACjB,IAAI,KAAK,IAAI,EAAE,EAAE;QACf,OAAO,QAAQ,CAAC,KAAK,CAAC;KACvB;IAED,QAAQ;IACR,IAAI,KAAK,IAAI,EAAE,EAAE;QACf,OAAO,QAAQ,CAAC,KAAK,CAAC;KACvB;IAED,OAAO;IACP,IAAI,KAAK,IAAI,EAAE,EAAE;QACf,OAAO,QAAQ,CAAC,IAAI,CAAC;KACtB;IAED,OAAO;IACP,IAAI,KAAK,IAAI,EAAE,EAAE;QACf,OAAO,QAAQ,CAAC,IAAI,CAAC;KACtB;IAED,qDAAqD;IACrD,4BAA4B;IAC5B,OAAO,QAAQ,CAAC,KAAK,CAAC;AACxB,CAAC"}
@@ -0,0 +1,2 @@
1
+ import { logtailTransport } from "./pino";
2
+ export default logtailTransport;
@@ -0,0 +1,3 @@
1
+ import { logtailTransport } from "./pino";
2
+ export default logtailTransport;
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,QAAQ,CAAC;AAE1C,eAAe,gBAAgB,CAAA"}
@@ -0,0 +1,3 @@
1
+ /// <reference types="node" />
2
+ import { PinoLokiOptionsContract } from './Contracts';
3
+ export default function (options: PinoLokiOptionsContract): Promise<import("stream").Transform & import("pino-abstract-transport").OnUnknown>;
@@ -0,0 +1,56 @@
1
+ var __asyncValues = (this && this.__asyncValues) || function (o) {
2
+ if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
3
+ var m = o[Symbol.asyncIterator], i;
4
+ return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i);
5
+ function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }
6
+ function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }
7
+ };
8
+ import build from 'pino-abstract-transport';
9
+ import { LogPusher } from './LogPusher';
10
+ export default async function (options) {
11
+ var _a, _b, _c, _d, _e, _f;
12
+ (_a = options.timeout) !== null && _a !== void 0 ? _a : ;
13
+ 30000;
14
+ (_b = options.silenceErrors) !== null && _b !== void 0 ? _b : ;
15
+ false;
16
+ (_c = options.batching) !== null && _c !== void 0 ? _c : ;
17
+ true;
18
+ (_d = options.interval) !== null && _d !== void 0 ? _d : ;
19
+ 5;
20
+ (_e = options.replaceTimestamp) !== null && _e !== void 0 ? _e : ;
21
+ false;
22
+ (_f = options.propsToLabels) !== null && _f !== void 0 ? _f : ;
23
+ [];
24
+ const logPusher = new LogPusher(options);
25
+ return build(async (source) => {
26
+ var e_1, _a;
27
+ let pinoLogBuffer = [];
28
+ if (options.batching) {
29
+ setInterval(async () => {
30
+ if (pinoLogBuffer.length === 0) {
31
+ return;
32
+ }
33
+ logPusher.push(pinoLogBuffer);
34
+ pinoLogBuffer = [];
35
+ }, options.interval * 1000);
36
+ }
37
+ try {
38
+ for (var source_1 = __asyncValues(source), source_1_1; source_1_1 = await source_1.next(), !source_1_1.done;) {
39
+ let obj = source_1_1.value;
40
+ if (options.batching) {
41
+ pinoLogBuffer.push(obj);
42
+ continue;
43
+ }
44
+ logPusher.push(obj);
45
+ }
46
+ }
47
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
48
+ finally {
49
+ try {
50
+ if (source_1_1 && !source_1_1.done && (_a = source_1.return)) await _a.call(source_1);
51
+ }
52
+ finally { if (e_1) throw e_1.error; }
53
+ }
54
+ });
55
+ }
56
+ //# sourceMappingURL=pino-loki-index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pino-loki-index.js","sourceRoot":"","sources":["../../src/pino-loki-index.ts"],"names":[],"mappings":";;;;;;;AAAA,OAAO,KAAK,MAAM,yBAAyB,CAAA;AAE3C,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA;AAEvC,MAAM,CAAC,OAAO,CAAC,KAAK,WAAW,OAAgC;;IAC7D,MAAA,OAAO,CAAC,OAAO,mCAAG,CAAA;IAAE,KAAK,CAAA;IACzB,MAAA,OAAO,CAAC,aAAa,mCAAG,CAAA;IAAE,KAAK,CAAA;IAC/B,MAAA,OAAO,CAAC,QAAQ,mCAAG,CAAA;IAAE,IAAI,CAAA;IACzB,MAAA,OAAO,CAAC,QAAQ,mCAAG,CAAA;IAAE,CAAC,CAAA;IACtB,MAAA,OAAO,CAAC,gBAAgB,mCAAG,CAAA;IAAE,KAAK,CAAA;IAClC,MAAA,OAAO,CAAC,aAAa,mCAAG,CAAA;IAAE,EAAE,CAAA;IAC5B,MAAM,SAAS,GAAG,IAAI,SAAS,CAAC,OAAO,CAAC,CAAA;IAExC,OAAO,KAAK,CAAC,KAAK,EAAE,MAAW,EAAE,EAAE;;QACjC,IAAI,aAAa,GAAc,EAAE,CAAA;QAEjC,IAAI,OAAO,CAAC,QAAQ,EAAE;YACpB,WAAW,CAAC,KAAK,IAAI,EAAE;gBACrB,IAAI,aAAa,CAAC,MAAM,KAAK,CAAC,EAAE;oBAC9B,OAAM;iBACP;gBAED,SAAS,CAAC,IAAI,CAAC,aAAa,CAAC,CAAA;gBAC7B,aAAa,GAAG,EAAE,CAAA;YACpB,CAAC,EAAE,OAAO,CAAC,QAAS,GAAG,IAAI,CAAC,CAAA;SAC7B;;YAED,KAAsB,IAAA,WAAA,cAAA,MAAM,CAAA,YAAA;gBAAjB,IAAI,GAAG,mBAAA,CAAA;gBAChB,IAAI,OAAO,CAAC,QAAQ,EAAE;oBACpB,aAAa,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;oBACvB,SAAQ;iBACT;gBAED,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;aACpB;;;;;;;;;IACH,CAAC,CAAC,CAAA;AACJ,CAAC"}
@@ -0,0 +1,11 @@
1
+ /// <reference types="node" />
2
+ import { ILogtailOptions } from "@logtail/types";
3
+ export interface PinoLog {
4
+ level: number;
5
+ [key: string]: any;
6
+ }
7
+ export interface IPinoLogtailOptions {
8
+ sourceToken: string;
9
+ options: Partial<ILogtailOptions>;
10
+ }
11
+ export declare function logtailTransport(options: IPinoLogtailOptions): Promise<import("stream").Transform & import("pino-abstract-transport").OnUnknown>;
@@ -0,0 +1,59 @@
1
+ var __asyncValues = (this && this.__asyncValues) || function (o) {
2
+ if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
3
+ var m = o[Symbol.asyncIterator], i;
4
+ return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i);
5
+ function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }
6
+ function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }
7
+ };
8
+ import build from 'pino-abstract-transport';
9
+ import { Logtail } from "@logtail/node";
10
+ import { getLogLevel } from "./helpers";
11
+ export async function logtailTransport(options) {
12
+ // FIXME: error handling for no source token
13
+ const logtail = new Logtail(options.sourceToken);
14
+ return build(async (source) => {
15
+ var e_1, _a;
16
+ try {
17
+ for (var source_1 = __asyncValues(source), source_1_1; source_1_1 = await source_1.next(), !source_1_1.done;) {
18
+ let obj = source_1_1.value;
19
+ // Log should have string `msg` key, > 0 length
20
+ if (typeof obj.msg !== "string" || !obj.msg.length) {
21
+ console.error('Field "msg" has to be a non-empty string.');
22
+ continue;
23
+ }
24
+ // Logging meta data
25
+ const meta = {};
26
+ // Copy `time` if set
27
+ if (typeof obj.time === "string" || obj.time.length) {
28
+ const time = new Date(obj.time);
29
+ if (!isNaN(time.valueOf())) {
30
+ meta.dt = time;
31
+ }
32
+ }
33
+ // Carry over any additional data fields
34
+ Object.keys(obj)
35
+ .filter(key => ["time", "msg", "level", "v"].indexOf(key) < 0)
36
+ .forEach(key => (meta[key] = obj[key]));
37
+ // Determine the log level
38
+ let level;
39
+ try {
40
+ level = getLogLevel(obj.level);
41
+ }
42
+ catch (_) {
43
+ console.error('Error while mapping log level.');
44
+ continue;
45
+ }
46
+ // Log to Logtail
47
+ logtail.log(obj.msg, level, meta);
48
+ }
49
+ }
50
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
51
+ finally {
52
+ try {
53
+ if (source_1_1 && !source_1_1.done && (_a = source_1.return)) await _a.call(source_1);
54
+ }
55
+ finally { if (e_1) throw e_1.error; }
56
+ }
57
+ });
58
+ }
59
+ //# sourceMappingURL=pino.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pino.js","sourceRoot":"","sources":["../../src/pino.ts"],"names":[],"mappings":";;;;;;;AAAA,OAAO,KAAK,MAAM,yBAAyB,CAAA;AAE3C,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAGxC,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAiBxC,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,OAA4B;IACjE,6CAA6C;IAC7C,MAAM,OAAO,GAAG,IAAI,OAAO,CAAC,OAAO,CAAC,WAAW,CAAC,CAAA;IAEhD,OAAO,KAAK,CAAC,KAAK,EAAE,MAAW,EAAE,EAAE;;;YACjC,KAAsB,IAAA,WAAA,cAAA,MAAM,CAAA,YAAA;gBAAjB,IAAI,GAAG,mBAAA,CAAA;gBAChB,+CAA+C;gBAC/C,IAAI,OAAO,GAAG,CAAC,GAAG,KAAK,QAAQ,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,EAAE;oBAClD,OAAO,CAAC,KAAK,CAAC,2CAA2C,CAAC,CAAA;oBAC1D,SAAQ;iBACT;gBAED,oBAAoB;gBACpB,MAAM,IAAI,GAAY,EAAE,CAAC;gBAEzB,qBAAqB;gBACrB,IAAI,OAAO,GAAG,CAAC,IAAI,KAAK,QAAQ,IAAI,GAAG,CAAC,IAAI,CAAC,MAAM,EAAE;oBACnD,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;oBAChC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,EAAE;wBAC1B,IAAI,CAAC,EAAE,GAAG,IAAI,CAAC;qBAChB;iBACF;gBAED,wCAAwC;gBACxC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC;qBACb,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;qBAC7D,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;gBAE1C,0BAA0B;gBAC1B,IAAI,KAAe,CAAC;gBAEpB,IAAI;oBACF,KAAK,GAAG,WAAW,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;iBAChC;gBAAC,OAAO,CAAC,EAAE;oBACV,OAAO,CAAC,KAAK,CAAC,gCAAgC,CAAC,CAAA;oBAC/C,SAAQ;iBACT;gBAED,iBAAiB;gBACjB,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC;aACnC;;;;;;;;;IACH,CAAC,CAAC,CAAA;AACJ,CAAC"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,112 @@
1
+ import pino from "pino";
2
+ import { Logtail } from "@logtail/node";
3
+ import { LogLevel } from "@logtail/types";
4
+ // Numeric log level test type
5
+ // type LevelTest = [number, LogLevel, LogLevelString];
6
+ // Sample log message
7
+ const message = "Something to do with something";
8
+ /**
9
+ * Create a Pino logger instance with Logtail transport
10
+ *
11
+ */
12
+ function createLogger() {
13
+ const token = "invalid source token";
14
+ const logtailOptions = { ignoreExceptions: true };
15
+ const options = { sourceToken: token, options: logtailOptions };
16
+ const transport = pino.transport({
17
+ target: "./pino.js",
18
+ options: options
19
+ });
20
+ return pino(transport);
21
+ }
22
+ /**
23
+ * Test a Bunyan log level vs. a Logtail `LogLevel`
24
+ *
25
+ * @param level LogLevelString - Bunyan log level (string)
26
+ * @param logLevel LogLevel - Logtail log level
27
+ * @param cb Function - Callback to execute to signal test completion
28
+ */
29
+ async function testLevel(level, logLevel, cb) {
30
+ // Logtail fixtures
31
+ const logtail = new Logtail("test", { batchInterval: 1 });
32
+ logtail.setSync(async (logs) => {
33
+ // Should be exactly one log
34
+ expect(logs.length).toBe(1);
35
+ // Message should match
36
+ expect(logs[0].message).toBe(message);
37
+ // Log level should be 'info'
38
+ expect(logs[0].level).toBe(logLevel);
39
+ // Signal that the test has finished
40
+ setImmediate(() => cb());
41
+ return logs;
42
+ });
43
+ // Create Bunyan logger
44
+ const logger = createLogger(logtail);
45
+ // Log out to Bunyan
46
+ logger[level](message);
47
+ }
48
+ describe("Bunyan tests", () => {
49
+ it("should log at the 'debug' level", async (done) => {
50
+ return testLevel("debug", LogLevel.Debug, done);
51
+ });
52
+ it("should log at the 'info' level", async (done) => {
53
+ return testLevel("info", LogLevel.Info, done);
54
+ });
55
+ it("should log at the 'warn' level", async (done) => {
56
+ return testLevel("warn", LogLevel.Warn, done);
57
+ });
58
+ it("should log at the 'error' level", async (done) => {
59
+ return testLevel("error", LogLevel.Error, done);
60
+ });
61
+ it("should log at the 'fatal' level", async (done) => {
62
+ return testLevel("fatal", LogLevel.Error, done);
63
+ });
64
+ it("should log using number levels", async (done) => {
65
+ // Fixtures
66
+ const levels = [
67
+ [25, LogLevel.Debug, "debug"],
68
+ [35, LogLevel.Info, "info"],
69
+ [45, LogLevel.Warn, "warn"],
70
+ [55, LogLevel.Error, "error"]
71
+ ];
72
+ const logtail = new Logtail("test", {
73
+ batchInterval: 1000,
74
+ batchSize: levels.length
75
+ });
76
+ logtail.setSync(async (logs) => {
77
+ expect(logs.length).toBe(levels.length);
78
+ done();
79
+ return logs;
80
+ });
81
+ // Create Bunyan logger
82
+ const logger = createLogger(logtail);
83
+ // Cycle through levels, and log
84
+ levels.forEach(level => logger[level[2]](message));
85
+ });
86
+ it("should include arbitrary extra data fields", async (done) => {
87
+ const logtail = new Logtail("test");
88
+ logtail.setSync(async (logs) => {
89
+ expect(logs).toHaveLength(1);
90
+ expect(logs[0].message).toEqual("i am the message");
91
+ expect(logs[0].foo).toEqual("bar");
92
+ expect(logs[0].some).toEqual({ nested: "stuff" });
93
+ done();
94
+ return logs;
95
+ });
96
+ const logger = createLogger(logtail);
97
+ logger.info({ foo: "bar", some: { nested: "stuff" } }, "i am the message");
98
+ });
99
+ it("should include correct context fields", async (done) => {
100
+ const logtail = new Logtail("test");
101
+ logtail.setSync(async (logs) => {
102
+ const context = logs[0].context;
103
+ const runtime = context.runtime;
104
+ expect(runtime.file).toEqual("bunyan.test.ts");
105
+ done();
106
+ return logs;
107
+ });
108
+ const logger = createLogger(logtail);
109
+ logger.info("message with context");
110
+ });
111
+ });
112
+ //# sourceMappingURL=pino.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pino.test.js","sourceRoot":"","sources":["../../src/pino.test.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,43 @@
1
+ {
2
+ "name": "@logtail/pino",
3
+ "version": "0.0.1",
4
+ "description": "Logtail Pino transport by Better Stack",
5
+ "keywords": [
6
+ "Better Stack",
7
+ "Logtail",
8
+ "logger",
9
+ "logging",
10
+ "node",
11
+ "pino",
12
+ "transport"
13
+ ],
14
+ "repository": "github.com/logtail/logtail-js.git",
15
+ "author": "Better Stack <hello@betterstack.com>",
16
+ "license": "ISC",
17
+ "main": "dist/cjs/index.js",
18
+ "module": "dist/es6/index.js",
19
+ "types": "dist/es6/index.d.ts",
20
+ "bugs": {
21
+ "url": "https://github.com/logtail/logtail-js/issues"
22
+ },
23
+ "devDependencies": {
24
+ "@logtail/node": "^0.1.15",
25
+ "npm-run-all": "^4.1.5",
26
+ "typescript": "^3.9.7"
27
+ },
28
+ "peerDependencies": {
29
+ "@logtail/node": "^0.1.0"
30
+ },
31
+ "dependencies": {
32
+ "@logtail/types": "^0.1.15",
33
+ "pino": "^8.8.0"
34
+ },
35
+ "scripts": {
36
+ "build:cjs": "tsc",
37
+ "build:es6": "tsc -p tsconfig.es6.json",
38
+ "build": "run-p build:*",
39
+ "prepublishOnly": "npm run build",
40
+ "test": "echo \"Error: run tests from root\" && exit 1"
41
+ },
42
+ "private": false
43
+ }
package/src/helpers.ts ADDED
@@ -0,0 +1,32 @@
1
+ import { LogLevel } from "@logtail/types";
2
+
3
+ /**
4
+ * Return a Logtail `LogLevel` based on the Pino level
5
+ * @param level number - Pino log level
6
+ */
7
+ export function getLogLevel(level: number): LogLevel {
8
+
9
+ // TODO: Trace 10
10
+ if (level <= 10) {
11
+ return LogLevel.Debug;
12
+ }
13
+
14
+ // Debug
15
+ if (level <= 20) {
16
+ return LogLevel.Debug;
17
+ }
18
+
19
+ // Info
20
+ if (level <= 30) {
21
+ return LogLevel.Info;
22
+ }
23
+
24
+ // Warn
25
+ if (level <= 40) {
26
+ return LogLevel.Warn;
27
+ }
28
+
29
+ // Everything above this level is considered an error
30
+ // TODO: Fatal 60 (Error 50)
31
+ return LogLevel.Error;
32
+ }
package/src/index.ts ADDED
@@ -0,0 +1,4 @@
1
+ import { logtailTransport } from "./pino";
2
+
3
+ export default logtailTransport
4
+
package/src/pino.ts ADDED
@@ -0,0 +1,65 @@
1
+ import build from 'pino-abstract-transport'
2
+
3
+ import { Logtail } from "@logtail/node";
4
+ import { Context, LogLevel, ILogtailOptions, StackContextHint } from "@logtail/types";
5
+
6
+ import { getLogLevel } from "./helpers";
7
+
8
+ // import { PinoLog, PinoLokiOptionsContract } from './Contracts'
9
+ // import { LogPusher } from './LogPusher'
10
+
11
+ // TODO: stackContextHint =
12
+
13
+ export interface PinoLog {
14
+ level: number
15
+ [key: string]: any
16
+ }
17
+
18
+ export interface IPinoLogtailOptions {
19
+ sourceToken: string,
20
+ options: Partial<ILogtailOptions>
21
+ }
22
+
23
+ export async function logtailTransport(options: IPinoLogtailOptions) {
24
+ // FIXME: error handling for no source token
25
+ const logtail = new Logtail(options.sourceToken)
26
+
27
+ return build(async (source: any) => {
28
+ for await (let obj of source) {
29
+ // Log should have string `msg` key, > 0 length
30
+ if (typeof obj.msg !== "string" || !obj.msg.length) {
31
+ console.error('Field "msg" has to be a non-empty string.')
32
+ continue
33
+ }
34
+
35
+ // Logging meta data
36
+ const meta: Context = {};
37
+
38
+ // Copy `time` if set
39
+ if (typeof obj.time === "string" || obj.time.length) {
40
+ const time = new Date(obj.time);
41
+ if (!isNaN(time.valueOf())) {
42
+ meta.dt = time;
43
+ }
44
+ }
45
+
46
+ // Carry over any additional data fields
47
+ Object.keys(obj)
48
+ .filter(key => ["time", "msg", "level", "v"].indexOf(key) < 0)
49
+ .forEach(key => (meta[key] = obj[key]));
50
+
51
+ // Determine the log level
52
+ let level: LogLevel;
53
+
54
+ try {
55
+ level = getLogLevel(obj.level);
56
+ } catch (_) {
57
+ console.error('Error while mapping log level.')
58
+ continue
59
+ }
60
+
61
+ // Log to Logtail
62
+ logtail.log(obj.msg, level, meta);
63
+ }
64
+ })
65
+ }
@@ -0,0 +1,7 @@
1
+ {
2
+ "extends": "./tsconfig.json",
3
+ "compilerOptions": {
4
+ "module": "es2015",
5
+ "outDir": "dist/es6"
6
+ }
7
+ }
package/tsconfig.json ADDED
@@ -0,0 +1,14 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "es2017" /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017','ES2018' or 'ESNEXT'. */,
4
+ "module": "commonjs" /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */,
5
+ "declaration": true /* Generates corresponding '.d.ts' file. */,
6
+ "sourceMap": true /* Generates corresponding '.map' file. */, // "outFile": "./", /* Concatenate and emit output to single file. */
7
+ "outDir": "dist/cjs" /* Redirect output structure to the directory. */,
8
+ "strict": true /* Enable all strict type-checking options. */,
9
+ "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */,
10
+ "moduleResolution": "node",
11
+ "resolveJsonModule": true
12
+ },
13
+ "include": ["./src"]
14
+ }