forked from aws/aws-lambda-nodejs-runtime-interface-client
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathFakeTelemetryTarget.js
130 lines (115 loc) · 3.37 KB
/
FakeTelemetryTarget.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
/**
* Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*/
'use strict';
const os = require('os');
const fs = require('fs');
const path = require('path');
const assert = require('assert');
const levels = Object.freeze({
TRACE: { name: 'TRACE', tlvMask: 0b00100 },
DEBUG: { name: 'DEBUG', tlvMask: 0b01000 },
INFO: { name: 'INFO', tlvMask: 0b01100 },
WARN: { name: 'WARN', tlvMask: 0b10000 },
ERROR: { name: 'ERROR', tlvMask: 0b10100 },
FATAL: { name: 'FATAL', tlvMask: 0b11000 },
});
const TextName = 'TEXT';
/**
* A fake implementation of the multilne logging protocol.
* Read and write log frames to a temp file and provide an asserting helper for
* reading individual log statements from the file.
*/
module.exports = class FakeTelemetryTarget {
constructor() {
this.readTarget = 0;
this.writeTarget = 0;
}
openFile() {
let tempTelemetryDir = fs.mkdtempSync(
path.join(os.tmpdir(), 'AWSLambdaNodeJsTelemetry-'),
);
this.writeTarget = fs.openSync(path.join(tempTelemetryDir, 'log'), 'as+');
this.readTarget = fs.openSync(path.join(tempTelemetryDir, 'log'), 'rs+');
console.log(
'Generate new telemetry file',
tempTelemetryDir,
'with file descriptor',
this.readTarget,
);
}
closeFile() {
console.log(`Close telemetry filedescriptor ${this.readTarget}`);
fs.closeSync(this.readTarget);
fs.closeSync(this.writeTarget);
this.readTarget = 0;
this.writeTarget = 0;
}
updateEnv() {
process.env['_LAMBDA_TELEMETRY_LOG_FD'] = this.writeTarget;
}
/**
* Read a single line from the telemetry file.
* Explodes when:
* - no line is present
* - the prefix is malformed
* - there aren't enough bytes
*/
readLine(level = 'INFO', format = TextName, expectEmpty = false) {
let readLength = () => {
let logPrefix = Buffer.alloc(16);
let actualReadBytes = fs.readSync(
this.readTarget,
logPrefix,
0,
logPrefix.length,
);
if (expectEmpty) {
assert.strictEqual(
actualReadBytes,
0,
`Expected actualReadBytes[${actualReadBytes}] = 0`,
);
return 0;
}
assert.strictEqual(
actualReadBytes,
logPrefix.length,
`Expected actualReadBytes[${actualReadBytes}] = ${logPrefix.length}`,
);
var _tlvHeader;
if (format === TextName)
_tlvHeader = (0xa55a0003 | levels[level].tlvMask) >>> 0;
else _tlvHeader = (0xa55a0002 | levels[level].tlvMask) >>> 0;
let _logIdentifier = Buffer.from(_tlvHeader.toString(16), 'hex');
assert.strictEqual(
logPrefix.lastIndexOf(_logIdentifier),
0,
`log prefix ${logPrefix.toString(
'hex',
)} should start with ${_logIdentifier.toString('hex')}`,
);
let len = logPrefix.readUInt32BE(4);
// discard the timestamp
logPrefix.readBigUInt64BE(8);
return len;
};
let lineLength = readLength();
if (lineLength === 0) {
return '';
}
let lineBytes = Buffer.alloc(lineLength);
let actualLineSize = fs.readSync(
this.readTarget,
lineBytes,
0,
lineBytes.length,
);
assert.strictEqual(
actualLineSize,
lineBytes.length,
'The log line must match the length specified in the frame header',
);
return lineBytes.toString('utf8');
}
};