Added logging & metrics to mailgun API calls
refs: https://github.com/TryGhost/Toolbox/issues/439 Adds timed metrics to ensure we know how long Mailgun takes to respond to queries - as well as the status codes we hit.
This commit is contained in:
parent
1221ba5d1d
commit
6ff34fb49f
@ -1,6 +1,7 @@
|
||||
const _ = require('lodash');
|
||||
const debug = require('@tryghost/debug');
|
||||
const logging = require('@tryghost/logging');
|
||||
const metrics = require('@tryghost/metrics');
|
||||
|
||||
module.exports = class MailgunClient {
|
||||
#config;
|
||||
@ -42,6 +43,7 @@ module.exports = class MailgunClient {
|
||||
|
||||
let messageData = {};
|
||||
|
||||
let startTime;
|
||||
try {
|
||||
const bulkEmailConfig = this.#config.get('bulkEmail');
|
||||
const messageContent = _.pick(message, 'subject', 'html', 'plaintext');
|
||||
@ -85,12 +87,22 @@ module.exports = class MailgunClient {
|
||||
}
|
||||
|
||||
const mailgunConfig = this.#getConfig();
|
||||
startTime = Date.now();
|
||||
const response = await mailgunInstance.messages.create(mailgunConfig.domain, messageData);
|
||||
metrics.metric('mailgun-send-mail', {
|
||||
value: Date.now() - startTime,
|
||||
statusCode: 200
|
||||
});
|
||||
|
||||
return {
|
||||
id: response.id
|
||||
};
|
||||
} catch (error) {
|
||||
logging.error(error);
|
||||
metrics.metric('mailgun-send-mail', {
|
||||
value: Date.now() - startTime,
|
||||
statusCode: error.status
|
||||
});
|
||||
return Promise.reject({error, messageData});
|
||||
}
|
||||
}
|
||||
@ -106,34 +118,54 @@ module.exports = class MailgunClient {
|
||||
|
||||
debug(`fetchEvents: starting fetching first events page`);
|
||||
const mailgunConfig = this.#getConfig();
|
||||
let page = await mailgunInstance.events.get(mailgunConfig.domain, mailgunOptions);
|
||||
let events = page?.items?.map(this.normalizeEvent) || [];
|
||||
debug(`fetchEvents: finished fetching first page with ${events.length} events`);
|
||||
let startTime = Date.now();
|
||||
try {
|
||||
let page = await mailgunInstance.events.get(mailgunConfig.domain, mailgunOptions);
|
||||
metrics.metric('mailgun-get-events', {
|
||||
value: Date.now() - startTime,
|
||||
statusCode: 200
|
||||
});
|
||||
let events = page?.items?.map(this.normalizeEvent) || [];
|
||||
debug(`fetchEvents: finished fetching first page with ${events.length} events`);
|
||||
|
||||
let eventCount = 0;
|
||||
let eventCount = 0;
|
||||
|
||||
pagesLoop:
|
||||
while (events.length !== 0) {
|
||||
const batchResult = await batchHandler(events);
|
||||
pagesLoop:
|
||||
while (events.length !== 0) {
|
||||
const batchResult = await batchHandler(events);
|
||||
|
||||
result = result.concat(batchResult);
|
||||
eventCount += events.length;
|
||||
result = result.concat(batchResult);
|
||||
eventCount += events.length;
|
||||
|
||||
if (eventCount >= maxEvents) {
|
||||
break pagesLoop;
|
||||
if (eventCount >= maxEvents) {
|
||||
break pagesLoop;
|
||||
}
|
||||
|
||||
const nextPageId = page.pages.next.page;
|
||||
debug(`fetchEvents: starting fetching next page ${nextPageId}`);
|
||||
startTime = Date.now();
|
||||
page = await mailgunInstance.events.get(mailgunConfig.domain, {
|
||||
page: nextPageId,
|
||||
...mailgunOptions
|
||||
});
|
||||
metrics.metric('mailgun-get-events', {
|
||||
value: Date.now() - startTime,
|
||||
statusCode: 200
|
||||
});
|
||||
events = page?.items?.map(this.normalizeEvent) || [];
|
||||
debug(`fetchEvents: finished fetching next page with ${events.length} events`);
|
||||
}
|
||||
|
||||
const nextPageId = page.pages.next.page;
|
||||
debug(`fetchEvents: starting fetching next page ${nextPageId}`);
|
||||
page = await mailgunInstance.events.get(mailgunConfig.domain, {
|
||||
page: nextPageId,
|
||||
...mailgunOptions
|
||||
return result;
|
||||
} catch (error) {
|
||||
// Log and re-throw Mailgun errors
|
||||
logging.error(error);
|
||||
metrics.metric('mailgun-get-events', {
|
||||
value: Date.now() - startTime,
|
||||
statusCode: error.status
|
||||
});
|
||||
events = page?.items?.map(this.normalizeEvent) || [];
|
||||
debug(`fetchEvents: finished fetching next page with ${events.length} events`);
|
||||
throw error;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
normalizeEvent(event) {
|
||||
|
@ -26,6 +26,7 @@
|
||||
"dependencies": {
|
||||
"@tryghost/debug": "0.1.18",
|
||||
"@tryghost/logging": "2.3.2",
|
||||
"@tryghost/metrics": "1.0.16",
|
||||
"form-data": "4.0.0",
|
||||
"lodash": "4.17.21",
|
||||
"mailgun.js": "8.0.1"
|
||||
|
65
yarn.lock
65
yarn.lock
@ -4270,7 +4270,7 @@
|
||||
"@tryghost/root-utils" "^0.3.16"
|
||||
debug "^4.3.1"
|
||||
|
||||
"@tryghost/elasticsearch@^3.0.4":
|
||||
"@tryghost/elasticsearch@^3.0.2", "@tryghost/elasticsearch@^3.0.4":
|
||||
version "3.0.4"
|
||||
resolved "https://registry.yarnpkg.com/@tryghost/elasticsearch/-/elasticsearch-3.0.4.tgz#f8572122bb34a0192471226d2c5c9e61d049a821"
|
||||
integrity sha512-ysExjEWI7VXWedmEbi757ub2avPRIZOAvzCWM5XC3vi9FyroW+invABmLfN9jsPX99eGpTWe1ENguslpLEvtdA==
|
||||
@ -4343,7 +4343,7 @@
|
||||
resolved "https://registry.yarnpkg.com/@tryghost/http-cache-utils/-/http-cache-utils-0.1.3.tgz#a3a07e55dbe3a62b7d51e98f19c063d03a1ef804"
|
||||
integrity sha512-QganheP/zhcpFnDLPJYlQ4gBIhd+lAEMh8byx7ocCPM37nuEQ3zlmcM6KzDfUmKYwU+5oI/ya/0Wn0kmnyZ37A==
|
||||
|
||||
"@tryghost/http-stream@^0.1.13":
|
||||
"@tryghost/http-stream@^0.1.10", "@tryghost/http-stream@^0.1.13":
|
||||
version "0.1.13"
|
||||
resolved "https://registry.yarnpkg.com/@tryghost/http-stream/-/http-stream-0.1.13.tgz#d7c60e0e6639a4d0c6f9446730ec4c2f8c7347a4"
|
||||
integrity sha512-SjYFH9RJkU4lsrLwewdhjryBAo+ladUu1yydg6eWtBgdwGZ5z0RmYANxkFL0jkyaw+6U7ntCKMfm6GI8HT7w+Q==
|
||||
@ -4471,7 +4471,24 @@
|
||||
lodash "^4.17.21"
|
||||
luxon "^1.26.0"
|
||||
|
||||
"@tryghost/logging@2.2.3", "@tryghost/logging@2.3.2", "@tryghost/logging@^2.2.3":
|
||||
"@tryghost/logging@2.2.3":
|
||||
version "2.2.3"
|
||||
resolved "https://registry.yarnpkg.com/@tryghost/logging/-/logging-2.2.3.tgz#40575a42e18b907a49cee5dfdfa62deb820954aa"
|
||||
integrity sha512-ACCm84U4HITt3mQhDSpyDLZetxzjYo4ux2MoSVGL3zxPfQBPFoI6hWEiSzYWX/4RGq2l2tR4di+5LWjIe8Ow6A==
|
||||
dependencies:
|
||||
"@tryghost/bunyan-rotating-filestream" "^0.0.7"
|
||||
"@tryghost/elasticsearch" "^3.0.2"
|
||||
"@tryghost/http-stream" "^0.1.10"
|
||||
"@tryghost/pretty-stream" "^0.1.11"
|
||||
"@tryghost/root-utils" "^0.3.15"
|
||||
bunyan "^1.8.15"
|
||||
bunyan-loggly "^1.4.2"
|
||||
fs-extra "^10.0.0"
|
||||
gelf-stream "^1.1.1"
|
||||
json-stringify-safe "^5.0.1"
|
||||
lodash "^4.17.21"
|
||||
|
||||
"@tryghost/logging@2.3.2", "@tryghost/logging@^2.2.3":
|
||||
version "2.3.2"
|
||||
resolved "https://registry.yarnpkg.com/@tryghost/logging/-/logging-2.3.2.tgz#31559c2f6eebb481a0ee8e9a958b2a2d8d55f82e"
|
||||
integrity sha512-XIKSNwcG1ARNzSakXXk0jX2Pph3LMHSXQAKAm9q50fKgvX5kMdyHlunmu/NikkFsctOF8MTBGm6BJ97QW3F5IA==
|
||||
@ -4576,6 +4593,15 @@
|
||||
chalk "^4.1.0"
|
||||
sywac "^1.3.0"
|
||||
|
||||
"@tryghost/pretty-stream@^0.1.11":
|
||||
version "0.1.13"
|
||||
resolved "https://registry.yarnpkg.com/@tryghost/pretty-stream/-/pretty-stream-0.1.13.tgz#392330e57ddb06fd89205eb58726445d5e6c02c8"
|
||||
integrity sha512-IpSdRxMRJqoy3WUbzwfz1UrBZADAoit24qnRREu71+/lC95ebk0cB2r6Gte2vwiFEuKJ2BFzu7iFRCZeH6jKvg==
|
||||
dependencies:
|
||||
lodash "^4.17.21"
|
||||
moment "^2.29.1"
|
||||
prettyjson "^1.2.5"
|
||||
|
||||
"@tryghost/pretty-stream@^0.1.12":
|
||||
version "0.1.12"
|
||||
resolved "https://registry.yarnpkg.com/@tryghost/pretty-stream/-/pretty-stream-0.1.12.tgz#e1991415610142d9895d3e5cb84ac838c58d8c8b"
|
||||
@ -19319,18 +19345,47 @@ mock-knex@TryGhost/mock-knex#8ecb8c227bf463c991c3d820d33f59efc3ab9682:
|
||||
lodash "^4.14.2"
|
||||
semver "^5.3.0"
|
||||
|
||||
moment-timezone@0.5.23, moment-timezone@0.5.34, moment-timezone@^0.5.23, moment-timezone@^0.5.31, moment-timezone@^0.5.33:
|
||||
moment-timezone@0.5.23, moment-timezone@^0.5.23:
|
||||
version "0.5.23"
|
||||
resolved "https://registry.yarnpkg.com/moment-timezone/-/moment-timezone-0.5.23.tgz#7cbb00db2c14c71b19303cb47b0fb0a6d8651463"
|
||||
integrity sha512-WHFH85DkCfiNMDX5D3X7hpNH3/PUhjTGcD0U1SgfBGZxJ3qUmJh5FdvaFjcClxOvB3rzdfj4oRffbI38jEnC1w==
|
||||
dependencies:
|
||||
moment ">= 2.9.0"
|
||||
|
||||
moment@2.24.0, moment@2.27.0, moment@2.29.1, moment@2.29.4, "moment@>= 2.9.0", moment@^2.10.2, moment@^2.18.1, moment@^2.19.3, moment@^2.27.0, moment@^2.29.1, moment@^2.29.3:
|
||||
moment-timezone@0.5.34:
|
||||
version "0.5.34"
|
||||
resolved "https://registry.yarnpkg.com/moment-timezone/-/moment-timezone-0.5.34.tgz#a75938f7476b88f155d3504a9343f7519d9a405c"
|
||||
integrity sha512-3zAEHh2hKUs3EXLESx/wsgw6IQdusOT8Bxm3D9UrHPQR7zlMmzwybC8zHEM1tQ4LJwP7fcxrWr8tuBg05fFCbg==
|
||||
dependencies:
|
||||
moment ">= 2.9.0"
|
||||
|
||||
moment-timezone@^0.5.31, moment-timezone@^0.5.33:
|
||||
version "0.5.37"
|
||||
resolved "https://registry.yarnpkg.com/moment-timezone/-/moment-timezone-0.5.37.tgz#adf97f719c4e458fdb12e2b4e87b8bec9f4eef1e"
|
||||
integrity sha512-uEDzDNFhfaywRl+vwXxffjjq1q0Vzr+fcQpQ1bU0kbzorfS7zVtZnCnGc8mhWmF39d4g4YriF6kwA75mJKE/Zg==
|
||||
dependencies:
|
||||
moment ">= 2.9.0"
|
||||
|
||||
moment@2.24.0, "moment@>= 2.9.0", moment@^2.10.2, moment@^2.18.1, moment@^2.19.3:
|
||||
version "2.24.0"
|
||||
resolved "https://registry.yarnpkg.com/moment/-/moment-2.24.0.tgz#0d055d53f5052aa653c9f6eb68bb5d12bf5c2b5b"
|
||||
integrity sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg==
|
||||
|
||||
moment@2.27.0:
|
||||
version "2.27.0"
|
||||
resolved "https://registry.yarnpkg.com/moment/-/moment-2.27.0.tgz#8bff4e3e26a236220dfe3e36de756b6ebaa0105d"
|
||||
integrity sha512-al0MUK7cpIcglMv3YF13qSgdAIqxHTO7brRtaz3DlSULbqfazqkc5kEjNrLDOM7fsjshoFIihnU8snrP7zUvhQ==
|
||||
|
||||
moment@2.29.1:
|
||||
version "2.29.1"
|
||||
resolved "https://registry.yarnpkg.com/moment/-/moment-2.29.1.tgz#b2be769fa31940be9eeea6469c075e35006fa3d3"
|
||||
integrity sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ==
|
||||
|
||||
moment@2.29.4, moment@^2.27.0, moment@^2.29.1, moment@^2.29.3:
|
||||
version "2.29.4"
|
||||
resolved "https://registry.yarnpkg.com/moment/-/moment-2.29.4.tgz#3dbe052889fe7c1b2ed966fcb3a77328964ef108"
|
||||
integrity sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w==
|
||||
|
||||
moo@^0.5.0, moo@^0.5.1:
|
||||
version "0.5.1"
|
||||
resolved "https://registry.yarnpkg.com/moo/-/moo-0.5.1.tgz#7aae7f384b9b09f620b6abf6f74ebbcd1b65dbc4"
|
||||
|
Loading…
Reference in New Issue
Block a user