|
1 | | -const moment = require('moment'); |
2 | 1 | const db = require('../../db'); |
3 | | -const logger = require('@medic/logger'); |
4 | | - |
5 | | -const LOG_TYPE = 'replication-fail-'; |
6 | | -// The count and month difference between old and new log. |
7 | | -// To determine when the old log will updated with the new one. |
8 | | -const LOG_COUNT_DIFF = 100; |
9 | | -const LOG_MONTH_DIFF = 1; |
10 | | - |
11 | | -const persistLog = async (info) => { |
12 | | - if (!info?.user) { |
13 | | - throw new Error('Error when persisting log: Log Information missing.'); |
14 | | - } |
15 | | - |
16 | | - const logDocId = LOG_TYPE + info.user; |
17 | | - |
18 | | - |
19 | | - |
20 | | - return db.medicLogs |
21 | | - .get(logDocId) |
22 | | - .catch(error => { |
23 | | - if (error.status === 404) { |
24 | | - return { _id: logDocId }; |
25 | | - } |
26 | | - throw error; |
27 | | - }) |
28 | | - .then(doc => { |
29 | | - if (!isLogDifferent(doc, info)) { |
30 | | - return; |
31 | | - } |
32 | | - |
33 | | - const logDoc = Object.assign(doc, info); |
34 | | - return db.medicLogs.put(logDoc); |
35 | | - }); |
36 | | -}; |
37 | | - |
38 | | -const isLogDifferent = (oldLog, newLog) => { |
39 | | - if (!oldLog.date && !oldLog.count) { |
40 | | - return true; |
41 | | - } |
| 2 | +const moment = require('moment'); |
42 | 3 |
|
43 | | - const countDiff = Math.abs(oldLog.count - newLog.count); |
| 4 | +const LOG_TYPE = 'replication-fail'; |
| 5 | +const MAX_FAILURES = 50; |
44 | 6 |
|
45 | | - const oldPrePurge = oldLog.all_docs_count || 0; |
46 | | - const newPrePurge = newLog.all_docs_count || 0; |
| 7 | +const captureFailure = async (userCtx, requestId, statusCode, duration) => { |
| 8 | + const log = await getLog(userCtx.name); |
47 | 9 |
|
48 | | - const prePurgeDiff = Math.abs(oldPrePurge - newPrePurge); |
| 10 | + const failure = { |
| 11 | + timestamp: moment().valueOf(), |
| 12 | + status_code: statusCode, |
| 13 | + duration: duration, |
| 14 | + request_id: requestId, |
| 15 | + subjects_count: userCtx.subjectsCount, |
| 16 | + roles: userCtx.roles, |
| 17 | + }; |
49 | 18 |
|
50 | | - if (countDiff > LOG_COUNT_DIFF || prePurgeDiff > LOG_COUNT_DIFF) { |
51 | | - return true; |
| 19 | + log.failures.push(failure); |
| 20 | + log.total_failures++; |
| 21 | + if (log.failures.length > MAX_FAILURES) { |
| 22 | + log.failures = log.failures.slice(-MAX_FAILURES); |
52 | 23 | } |
53 | 24 |
|
54 | | - const oldLogDate = moment(oldLog.date); |
55 | | - const newLogDate = moment(newLog.date); |
56 | | - const monthDiff = newLogDate.diff(oldLogDate, 'months', true); |
57 | | - |
58 | | - return monthDiff > LOG_MONTH_DIFF; |
59 | | -}; |
60 | | - |
61 | | -const getLogsByType = (docPrefix) => { |
62 | | - const options = { |
63 | | - startkey: docPrefix, |
64 | | - endkey: docPrefix + '\ufff0', |
65 | | - include_docs: true |
66 | | - }; |
67 | | - |
68 | | - return db.medicLogs |
69 | | - .allDocs(options) |
70 | | - .then((result) => result.rows.map(row => row.doc)); |
| 25 | + return db.medicLogs.put(log); |
71 | 26 | }; |
| 27 | +const getDocId = (userName) => `${LOG_TYPE}-${moment().format('YYYY-MM')}-${userName}`; |
72 | 28 |
|
73 | | -const getReplicationLimitLog = (userName) => { |
74 | | - const get = !userName ? getLogsByType(LOG_TYPE) : db.medicLogs.get(LOG_TYPE + userName); |
| 29 | +const getLog = async (userName) => { |
| 30 | + const docId = getDocId(userName); |
75 | 31 |
|
76 | | - return get |
77 | | - .then(logs => { |
| 32 | + try { |
| 33 | + return await db.medicLogs.get(docId); |
| 34 | + } catch (err) { |
| 35 | + if (err.status === 404) { |
78 | 36 | return { |
79 | | - limit: DOC_IDS_WARN_LIMIT, |
80 | | - users: logs |
| 37 | + _id: docId, |
| 38 | + type: LOG_TYPE, |
| 39 | + user: userName, |
| 40 | + timestamp: moment().valueOf(), |
| 41 | + total_failures: 0, |
| 42 | + failures: [], |
81 | 43 | }; |
82 | | - }); |
83 | | -}; |
84 | | - |
85 | | -const logReplicationLimit = (userName, count, prePurgeCount) => { |
86 | | - const info = { |
87 | | - user: userName, |
88 | | - date: moment().valueOf(), |
89 | | - count, |
90 | | - all_docs_count: prePurgeCount |
91 | | - }; |
92 | | - |
93 | | - return persistLog(info) |
94 | | - .catch(error => { |
95 | | - logger.error('Error on Log Replication Limit %o', error); |
96 | | - }); |
| 44 | + } |
| 45 | + throw err; |
| 46 | + } |
97 | 47 | }; |
98 | 48 |
|
99 | 49 | module.exports = { |
100 | | - put: logReplicationLimit, |
101 | | - get: getReplicationLimitLog, |
102 | | - _isLogDifferent: isLogDifferent, |
103 | | - LOG_TYPE, |
104 | | - DOC_IDS_WARN_LIMIT, |
| 50 | + capture: captureFailure, |
105 | 51 | }; |
0 commit comments