forked from aws/aws-lambda-nodejs-runtime-interface-client
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathFakeTelemetryTarget.js
129 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
/**
* 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');
}
};