forked from fippo/rtcstats-server
-
Notifications
You must be signed in to change notification settings - Fork 23
Expand file tree
/
Copy pathDumpPersister.js
More file actions
94 lines (76 loc) · 3.27 KB
/
DumpPersister.js
File metadata and controls
94 lines (76 loc) · 3.27 KB
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
const logger = require('./logging');
const PromCollector = require('./metrics/PromCollector');
const { saveEntryAssureUnique } = require('./store/dynamo');
const initS3Store = require('./store/s3.js');
const { asyncDeleteFile, getDumpPath } = require('./utils/utils');
/**
*
*/
class DumpPersister {
/**
*
*/
constructor({ tempPath, s3Config, disableFeatExtraction, webhookSender, config }) {
this.tempPath = tempPath;
this.store = this.createDumpStorage(s3Config);
this.disableFeatExtraction = disableFeatExtraction;
this.webhookSender = webhookSender;
this.config = config;
}
/**
* Initialize the service which will persist the dump files.
*/
createDumpStorage(s3Config) {
if (s3Config?.region) {
return initS3Store(s3Config);
}
logger.warn('[DumpPersister] S3 is not configured!');
}
/**
* Persist the dump file to the configured store and save the associated metadata. At the time of writing the
* only supported store for metadata is dynamo.
*
* @param {Object} sinkMeta - metadata associated with the dump file.
*/
async persistDumpData(sinkMeta) {
// Metadata associated with a dump can get large so just select the necessary fields.
const { clientId } = sinkMeta;
let uniqueClientId = clientId;
// Because of the current reconnect mechanism some files might have the same clientId, in which case the
// underlying call will add an associated uniqueId to the clientId and return it.
uniqueClientId = await saveEntryAssureUnique(sinkMeta);
// Store the dump file associated with the clientId using uniqueClientId as the key value. In the majority of
// cases the input parameter will have the same values.
this.storeDump(sinkMeta, uniqueClientId ?? clientId);
}
/**
* Store the dump to the configured store. The dump file might be stored under a different
* name, this is to account for the reconnect mechanism currently in place.
*
* @param {string} sinkMeta - name that the dump file will actually have on disk.
* @param {string} uniqueClientId - name that the dump will have on the store.
*/
async storeDump(sinkMeta, uniqueClientId) {
const {
clientId,
isJaaSTenant
} = sinkMeta;
const dumpPath = getDumpPath(this.tempPath, clientId);
const { webhooks: { sendRtcstatsUploaded } = { sendRtcstatsUploaded: false } } = this.config;
try {
logger.info(`[S3] Storing dump ${uniqueClientId} with path ${dumpPath}`);
await this.store?.put(uniqueClientId, dumpPath);
if (isJaaSTenant && sendRtcstatsUploaded && this.webhookSender) {
const signedLink = await this.store?.getSignedUrl(uniqueClientId);
logger.info('[App] Signed url:', signedLink);
this.webhookSender.sendRtcstatsUploadedHook(sinkMeta, signedLink);
}
} catch (err) {
PromCollector.storageErrorCount.inc();
logger.error('Error storing: %s uniqueId: %s - %s', dumpPath, uniqueClientId, err);
} finally {
await asyncDeleteFile(dumpPath);
}
}
}
module.exports = DumpPersister;