@payfit/audit-log 3.5.0-rc.20 → 3.5.0-rc.22

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.
@@ -0,0 +1,2 @@
1
+ export declare function compress(input: string): string;
2
+ export declare function decompress(input: string): string;
@@ -0,0 +1 @@
1
+ export {};
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- "use strict";var v=Object.defineProperty;var p=(s,t,e)=>t in s?v(s,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):s[t]=e;var n=(s,t,e)=>(p(s,typeof t!="symbol"?t+"":t,e),e);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const f=require("uuid"),o=require("winston"),S=require("hot-shots"),m=require("@aws-sdk/client-sqs"),E="audit-logs",_="@payfit/audit-log",L=()=>{const s=process.env.LOG_LEVEL;return s&&s.trim()!==""?s.trim():"info"},q=(s,t)=>o.createLogger({level:L(),silent:process.env.NODE_ENV==="test",exitOnError:!1,defaultMeta:{namespace:E,sdk:_,service:s,environment:t},format:o.format.combine(o.format.timestamp(),o.format.errors({stack:!0}),o.format.json()),transports:[new o.transports.Console]}),y="payfit.audit-logs.",d=s=>Object.entries(s).filter(([,t])=>t!==void 0&&t!=="").map(([t,e])=>`${t}:${String(e)}`);class A{constructor(){n(this,"client");this.client=new S.StatsD({prefix:y,errorHandler:()=>{},cacheDns:!0})}increment(t,e){this.client.increment(t,1,d(e))}histogram(t,e,i){this.client.histogram(t,e,d(i))}async close(){await new Promise(t=>{this.client.close(()=>t())})}}const M=()=>new A,D="eu-west-3",U={dev:"https://sqs.eu-west-3.amazonaws.com/533547282673/audit-logs-ingest",staging:"https://sqs.eu-west-3.amazonaws.com/589883667243/audit-logs-ingest",prod:"https://sqs.eu-west-3.amazonaws.com/614948436281/audit-logs-ingest"},C={working:"staging",production:"prod"};class O{constructor(t){n(this,"environment");n(this,"client");n(this,"queueUrl");this.environment=t;const e=C[t]??t,i=U[e];if(!i)throw new Error(`audit-logs SDK: no SQS queue URL configured for environment "${t}"`);this.queueUrl=i,this.client=new m.SQSClient({region:D})}async create(t){await this.client.send(new m.SendMessageCommand({QueueUrl:this.queueUrl,MessageBody:JSON.stringify(t)}))}}class N{constructor(t,e={}){n(this,"params");n(this,"transport");n(this,"logger");n(this,"metrics");this.params=t,this.transport=e.transport??new O(t.environment),this.logger=e.logger??q(t.service,t.environment),this.metrics=e.metrics??M()}async log({scope:t,account:e,...i}){const h=f.v4(),{environment:c,service:g}=this.params,r={...i,...e,service:g,id:h,environment:c,...t&&{scope:t}},a={service:g,environment:c,namespace:r.namespace,event:r.event,target:r.target},l=Date.now();try{await this.transport.create(r),this.metrics.increment("sent",a),this.metrics.histogram("send_duration_ms",Date.now()-l,a),this.logger.debug("audit-log sent",{id:r.id,event:r.event,target:r.target})}catch(w){this.metrics.increment("send_failed",a),this.metrics.histogram("send_duration_ms",Date.now()-l,a);const u=w.message;try{this.logger.error("audit-log write failed",{audit_log:r,error:u})}catch{this.metrics.increment("serialization_failed",a);try{this.logger.error("audit-log write failed (serialization failed)",{audit_log_meta:{id:r.id,service:r.service,environment:r.environment,namespace:r.namespace,event:r.event,target:r.target},error:u})}catch{}}}}}exports.AuditLogger=N;
1
+ "use strict";var w=Object.defineProperty;var p=(s,e,t)=>e in s?w(s,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):s[e]=t;var i=(s,e,t)=>(p(s,typeof e!="symbol"?e+"":e,t),t);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const v=require("uuid"),a=require("winston"),S=require("hot-shots"),d=require("@aws-sdk/client-sqs"),E=require("zlib"),y="audit-logs",_="@payfit/audit-log",q=()=>{const s=process.env.LOG_LEVEL;return s&&s.trim()!==""?s.trim():"info"},L=(s,e)=>a.createLogger({level:q(),silent:process.env.NODE_ENV==="test",exitOnError:!1,defaultMeta:{namespace:y,sdk:_,service:s,environment:e},format:a.format.combine(a.format.timestamp(),a.format.errors({stack:!0}),a.format.json()),transports:[new a.transports.Console]}),M="payfit.audit-logs.",h=s=>Object.entries(s).filter(([,e])=>e!==void 0&&e!=="").map(([e,t])=>`${e}:${String(t)}`);class A{constructor(){i(this,"client");this.client=new S.StatsD({prefix:M,errorHandler:()=>{},cacheDns:!0})}increment(e,t){this.client.increment(e,1,h(t))}histogram(e,t,n){this.client.histogram(e,t,h(n))}async close(){await new Promise(e=>{this.client.close(()=>e())})}}const b=()=>new A;function C(s){return E.brotliCompressSync(Buffer.from(s,"utf8")).toString("base64")}function U(s){return s instanceof Error&&s.message.includes("Message must be shorter than")}const O="eu-west-3",z={dev:"https://sqs.eu-west-3.amazonaws.com/533547282673/audit-logs-ingest",staging:"https://sqs.eu-west-3.amazonaws.com/589883667243/audit-logs-ingest",prod:"https://sqs.eu-west-3.amazonaws.com/614948436281/audit-logs-ingest"},D={working:"staging",production:"prod"};class N{constructor(e,t){i(this,"environment");i(this,"logger");i(this,"client");i(this,"queueUrl");this.environment=e,this.logger=t;const n=D[e]??e,o=z[n];if(!o)throw new Error(`audit-logs SDK: no SQS queue URL configured for environment "${e}"`);this.queueUrl=o,this.client=new d.SQSClient({region:O})}async create(e){var n;const t=JSON.stringify(e);try{await this.send(t)}catch(o){if(!U(o))throw o;(n=this.logger)==null||n.info("audit-log payload exceeds the SQS size limit, retrying with Brotli compression",{id:e.id,namespace:e.namespace}),await this.send(C(t))}}async send(e){await this.client.send(new d.SendMessageCommand({QueueUrl:this.queueUrl,MessageBody:e}))}}class Q{constructor(e,t={}){i(this,"params");i(this,"transport");i(this,"logger");i(this,"metrics");this.params=e,this.logger=t.logger??L(e.service,e.environment),this.transport=t.transport??new N(e.environment,this.logger),this.metrics=t.metrics??b()}async log({scope:e,account:t,...n}){const o=v.v4(),{environment:g,service:l}=this.params,r={...n,...t,service:l,id:o,environment:g,...e&&{scope:e}},c={service:l,environment:g,namespace:r.namespace,event:r.event,target:r.target},m=Date.now();try{await this.transport.create(r),this.metrics.increment("sent",c),this.metrics.histogram("send_duration_ms",Date.now()-m,c),this.logger.debug("audit-log sent",{id:r.id,event:r.event,target:r.target})}catch(f){this.metrics.increment("send_failed",c),this.metrics.histogram("send_duration_ms",Date.now()-m,c);const u=f.message;try{this.logger.error("audit-log write failed",{audit_log:r,error:u})}catch{this.metrics.increment("serialization_failed",c);try{this.logger.error("audit-log write failed (serialization failed)",{audit_log_meta:{id:r.id,service:r.service,environment:r.environment,namespace:r.namespace,event:r.event,target:r.target},error:u})}catch{}}}}}exports.AuditLogger=Q;
package/dist/index.mjs CHANGED
@@ -1,114 +1,134 @@
1
1
  var p = Object.defineProperty;
2
- var w = (s, t, e) => t in s ? p(s, t, { enumerable: !0, configurable: !0, writable: !0, value: e }) : s[t] = e;
3
- var i = (s, t, e) => (w(s, typeof t != "symbol" ? t + "" : t, e), e);
4
- import { v4 as v } from "uuid";
5
- import { createLogger as f, format as a, transports as E } from "winston";
6
- import { StatsD as _ } from "hot-shots";
7
- import { SQSClient as S, SendMessageCommand as L } from "@aws-sdk/client-sqs";
8
- const y = "audit-logs", A = "@payfit/audit-log", D = () => {
2
+ var f = (s, e, t) => e in s ? p(s, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : s[e] = t;
3
+ var i = (s, e, t) => (f(s, typeof e != "symbol" ? e + "" : e, t), t);
4
+ import { v4 as w } from "uuid";
5
+ import { createLogger as v, format as c, transports as S } from "winston";
6
+ import { StatsD as E } from "hot-shots";
7
+ import { SQSClient as _, SendMessageCommand as y } from "@aws-sdk/client-sqs";
8
+ import { brotliCompressSync as L } from "zlib";
9
+ const M = "audit-logs", A = "@payfit/audit-log", C = () => {
9
10
  const s = process.env.LOG_LEVEL;
10
11
  return s && s.trim() !== "" ? s.trim() : "info";
11
- }, M = (s, t) => f({
12
- level: D(),
12
+ }, U = (s, e) => v({
13
+ level: C(),
13
14
  silent: process.env.NODE_ENV === "test",
14
15
  exitOnError: !1,
15
16
  defaultMeta: {
16
- namespace: y,
17
+ namespace: M,
17
18
  sdk: A,
18
19
  service: s,
19
- environment: t
20
+ environment: e
20
21
  },
21
- format: a.combine(a.timestamp(), a.errors({ stack: !0 }), a.json()),
22
- transports: [new E.Console()]
23
- }), U = "payfit.audit-logs.", d = (s) => Object.entries(s).filter(([, t]) => t !== void 0 && t !== "").map(([t, e]) => `${t}:${String(e)}`);
24
- class q {
22
+ format: c.combine(c.timestamp(), c.errors({ stack: !0 }), c.json()),
23
+ transports: [new S.Console()]
24
+ }), q = "payfit.audit-logs.", u = (s) => Object.entries(s).filter(([, e]) => e !== void 0 && e !== "").map(([e, t]) => `${e}:${String(t)}`);
25
+ class b {
25
26
  constructor() {
26
27
  i(this, "client");
27
- this.client = new _({
28
- prefix: U,
28
+ this.client = new E({
29
+ prefix: q,
29
30
  // Loss of metrics never breaks the caller — DogStatsD UDP is best-effort by design.
30
31
  errorHandler: () => {
31
32
  },
32
33
  cacheDns: !0
33
34
  });
34
35
  }
35
- increment(t, e) {
36
- this.client.increment(t, 1, d(e));
36
+ increment(e, t) {
37
+ this.client.increment(e, 1, u(t));
37
38
  }
38
- histogram(t, e, n) {
39
- this.client.histogram(t, e, d(n));
39
+ histogram(e, t, n) {
40
+ this.client.histogram(e, t, u(n));
40
41
  }
41
42
  async close() {
42
- await new Promise((t) => {
43
- this.client.close(() => t());
43
+ await new Promise((e) => {
44
+ this.client.close(() => e());
44
45
  });
45
46
  }
46
47
  }
47
- const C = () => new q(), N = "eu-west-3", O = {
48
+ const D = () => new b();
49
+ function N(s) {
50
+ return L(Buffer.from(s, "utf8")).toString("base64");
51
+ }
52
+ function O(s) {
53
+ return s instanceof Error && s.message.includes("Message must be shorter than");
54
+ }
55
+ const z = "eu-west-3", Q = {
48
56
  dev: "https://sqs.eu-west-3.amazonaws.com/533547282673/audit-logs-ingest",
49
57
  staging: "https://sqs.eu-west-3.amazonaws.com/589883667243/audit-logs-ingest",
50
58
  prod: "https://sqs.eu-west-3.amazonaws.com/614948436281/audit-logs-ingest"
51
- }, z = {
59
+ }, R = {
52
60
  working: "staging",
53
61
  production: "prod"
54
62
  };
55
- class R {
56
- constructor(t) {
63
+ class k {
64
+ constructor(e, t) {
57
65
  i(this, "environment");
66
+ i(this, "logger");
58
67
  i(this, "client");
59
68
  i(this, "queueUrl");
60
- this.environment = t;
61
- const e = z[t] ?? t, n = O[e];
62
- if (!n)
63
- throw new Error(`audit-logs SDK: no SQS queue URL configured for environment "${t}"`);
64
- this.queueUrl = n, this.client = new S({ region: N });
69
+ this.environment = e, this.logger = t;
70
+ const n = R[e] ?? e, o = Q[n];
71
+ if (!o)
72
+ throw new Error(`audit-logs SDK: no SQS queue URL configured for environment "${e}"`);
73
+ this.queueUrl = o, this.client = new _({ region: z });
74
+ }
75
+ async create(e) {
76
+ var n;
77
+ const t = JSON.stringify(e);
78
+ try {
79
+ await this.send(t);
80
+ } catch (o) {
81
+ if (!O(o))
82
+ throw o;
83
+ (n = this.logger) == null || n.info("audit-log payload exceeds the SQS size limit, retrying with Brotli compression", { id: e.id, namespace: e.namespace }), await this.send(N(t));
84
+ }
65
85
  }
66
- async create(t) {
67
- await this.client.send(new L({
86
+ async send(e) {
87
+ await this.client.send(new y({
68
88
  QueueUrl: this.queueUrl,
69
- MessageBody: JSON.stringify(t)
89
+ MessageBody: e
70
90
  }));
71
91
  }
72
92
  }
73
- class x {
74
- constructor(t, e = {}) {
93
+ class V {
94
+ constructor(e, t = {}) {
75
95
  i(this, "params");
76
96
  i(this, "transport");
77
97
  i(this, "logger");
78
98
  i(this, "metrics");
79
- this.params = t, this.transport = e.transport ?? new R(t.environment), this.logger = e.logger ?? M(t.service, t.environment), this.metrics = e.metrics ?? C();
99
+ this.params = e, this.logger = t.logger ?? U(e.service, e.environment), this.transport = t.transport ?? new k(e.environment, this.logger), this.metrics = t.metrics ?? D();
80
100
  }
81
- async log({ scope: t, account: e, ...n }) {
82
- const u = v(), { environment: c, service: g } = this.params, r = {
101
+ async log({ scope: e, account: t, ...n }) {
102
+ const o = w(), { environment: g, service: l } = this.params, r = {
83
103
  ...n,
84
- ...e,
85
- service: g,
86
- id: u,
87
- environment: c,
88
- ...t && { scope: t }
89
- }, o = {
90
- service: g,
91
- environment: c,
104
+ ...t,
105
+ service: l,
106
+ id: o,
107
+ environment: g,
108
+ ...e && { scope: e }
109
+ }, a = {
110
+ service: l,
111
+ environment: g,
92
112
  namespace: r.namespace,
93
113
  event: r.event,
94
114
  target: r.target
95
- }, l = Date.now();
115
+ }, m = Date.now();
96
116
  try {
97
- await this.transport.create(r), this.metrics.increment("sent", o), this.metrics.histogram("send_duration_ms", Date.now() - l, o), this.logger.debug("audit-log sent", {
117
+ await this.transport.create(r), this.metrics.increment("sent", a), this.metrics.histogram("send_duration_ms", Date.now() - m, a), this.logger.debug("audit-log sent", {
98
118
  id: r.id,
99
119
  event: r.event,
100
120
  target: r.target
101
121
  });
102
122
  } catch (h) {
103
- this.metrics.increment("send_failed", o), this.metrics.histogram("send_duration_ms", Date.now() - l, o);
104
- const m = h.message;
123
+ this.metrics.increment("send_failed", a), this.metrics.histogram("send_duration_ms", Date.now() - m, a);
124
+ const d = h.message;
105
125
  try {
106
126
  this.logger.error("audit-log write failed", {
107
127
  audit_log: r,
108
- error: m
128
+ error: d
109
129
  });
110
130
  } catch {
111
- this.metrics.increment("serialization_failed", o);
131
+ this.metrics.increment("serialization_failed", a);
112
132
  try {
113
133
  this.logger.error("audit-log write failed (serialization failed)", {
114
134
  audit_log_meta: {
@@ -119,7 +139,7 @@ class x {
119
139
  event: r.event,
120
140
  target: r.target
121
141
  },
122
- error: m
142
+ error: d
123
143
  });
124
144
  } catch {
125
145
  }
@@ -128,5 +148,5 @@ class x {
128
148
  }
129
149
  }
130
150
  export {
131
- x as AuditLogger
151
+ V as AuditLogger
132
152
  };
@@ -1,8 +1,11 @@
1
+ import type { Logger } from 'winston';
1
2
  import { IAuditLogCreationData, IAuditLogTransport } from './interface';
2
3
  export declare class Transport implements IAuditLogTransport {
3
4
  protected environment: string;
5
+ private logger?;
4
6
  private client;
5
7
  private queueUrl;
6
- constructor(environment: string);
8
+ constructor(environment: string, logger?: Logger | undefined);
7
9
  create(auditLogData: IAuditLogCreationData): Promise<void>;
10
+ private send;
8
11
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@payfit/audit-log",
3
- "version": "3.5.0-rc.20",
3
+ "version": "3.5.0-rc.22",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "https://github.com/PayFit/audit-logs.git",