Send to zulip

This commit is contained in:
Koper
2023-11-20 21:39:33 +07:00
parent 82f50817f8
commit ba40d28152
3609 changed files with 2311843 additions and 7 deletions

View File

@@ -0,0 +1,82 @@
var AWS = require('../core');
/**
* Resolve client-side monitoring configuration from either environmental variables
* or shared config file. Configurations from environmental variables have higher priority
* than those from shared config file. The resolver will try to read the shared config file
* no matter whether the AWS_SDK_LOAD_CONFIG variable is set.
* @api private
*/
function resolveMonitoringConfig() {
var config = {
port: undefined,
clientId: undefined,
enabled: undefined,
host: undefined
};
if (fromEnvironment(config) || fromConfigFile(config)) return toJSType(config);
return toJSType(config);
}
/**
* Resolve configurations from environmental variables.
* @param {object} client side monitoring config object needs to be resolved
* @returns {boolean} whether resolving configurations is done
* @api private
*/
function fromEnvironment(config) {
config.port = config.port || process.env.AWS_CSM_PORT;
config.enabled = config.enabled || process.env.AWS_CSM_ENABLED;
config.clientId = config.clientId || process.env.AWS_CSM_CLIENT_ID;
config.host = config.host || process.env.AWS_CSM_HOST;
return config.port && config.enabled && config.clientId && config.host ||
['false', '0'].indexOf(config.enabled) >= 0; //no need to read shared config file if explicitely disabled
}
/**
* Resolve cofigurations from shared config file with specified role name
* @param {object} client side monitoring config object needs to be resolved
* @returns {boolean} whether resolving configurations is done
* @api private
*/
function fromConfigFile(config) {
var sharedFileConfig;
try {
var configFile = AWS.util.iniLoader.loadFrom({
isConfig: true,
filename: process.env[AWS.util.sharedConfigFileEnv]
});
var sharedFileConfig = configFile[
process.env.AWS_PROFILE || AWS.util.defaultProfile
];
} catch (err) {
return false;
}
if (!sharedFileConfig) return config;
config.port = config.port || sharedFileConfig.csm_port;
config.enabled = config.enabled || sharedFileConfig.csm_enabled;
config.clientId = config.clientId || sharedFileConfig.csm_client_id;
config.host = config.host || sharedFileConfig.csm_host;
return config.port && config.enabled && config.clientId && config.host;
}
/**
* Transfer the resolved configuration value to proper types: port as number, enabled
* as boolean and clientId as string. The 'enabled' flag is valued to false when set
* to 'false' or '0'.
* @param {object} resolved client side monitoring config
* @api private
*/
function toJSType(config) {
//config.XXX is either undefined or string
var falsyNotations = ['false', '0', undefined];
if (!config.enabled || falsyNotations.indexOf(config.enabled.toLowerCase()) >= 0) {
config.enabled = false;
} else {
config.enabled = true;
}
config.port = config.port ? parseInt(config.port, 10) : undefined;
return config;
}
module.exports = resolveMonitoringConfig;

View File

@@ -0,0 +1,125 @@
var util = require('../core').util;
var dgram = require('dgram');
var stringToBuffer = util.buffer.toBuffer;
var MAX_MESSAGE_SIZE = 1024 * 8; // 8 KB
/**
* Publishes metrics via udp.
* @param {object} options Paramters for Publisher constructor
* @param {number} [options.port = 31000] Port number
* @param {string} [options.clientId = ''] Client Identifier
* @param {boolean} [options.enabled = false] enable sending metrics datagram
* @api private
*/
function Publisher(options) {
// handle configuration
options = options || {};
this.enabled = options.enabled || false;
this.port = options.port || 31000;
this.clientId = options.clientId || '';
this.address = options.host || '127.0.0.1';
if (this.clientId.length > 255) {
// ClientId has a max length of 255
this.clientId = this.clientId.substr(0, 255);
}
this.messagesInFlight = 0;
}
Publisher.prototype.fieldsToTrim = {
UserAgent: 256,
SdkException: 128,
SdkExceptionMessage: 512,
AwsException: 128,
AwsExceptionMessage: 512,
FinalSdkException: 128,
FinalSdkExceptionMessage: 512,
FinalAwsException: 128,
FinalAwsExceptionMessage: 512
};
/**
* Trims fields that have a specified max length.
* @param {object} event ApiCall or ApiCallAttempt event.
* @returns {object}
* @api private
*/
Publisher.prototype.trimFields = function(event) {
var trimmableFields = Object.keys(this.fieldsToTrim);
for (var i = 0, iLen = trimmableFields.length; i < iLen; i++) {
var field = trimmableFields[i];
if (event.hasOwnProperty(field)) {
var maxLength = this.fieldsToTrim[field];
var value = event[field];
if (value && value.length > maxLength) {
event[field] = value.substr(0, maxLength);
}
}
}
return event;
};
/**
* Handles ApiCall and ApiCallAttempt events.
* @param {Object} event apiCall or apiCallAttempt event.
* @api private
*/
Publisher.prototype.eventHandler = function(event) {
// set the clientId
event.ClientId = this.clientId;
this.trimFields(event);
var message = stringToBuffer(JSON.stringify(event));
if (!this.enabled || message.length > MAX_MESSAGE_SIZE) {
// drop the message if publisher not enabled or it is too large
return;
}
this.publishDatagram(message);
};
/**
* Publishes message to an agent.
* @param {Buffer} message JSON message to send to agent.
* @api private
*/
Publisher.prototype.publishDatagram = function(message) {
var self = this;
var client = this.getClient();
this.messagesInFlight++;
this.client.send(message, 0, message.length, this.port, this.address, function(err, bytes) {
if (--self.messagesInFlight <= 0) {
// destroy existing client so the event loop isn't kept open
self.destroyClient();
}
});
};
/**
* Returns an existing udp socket, or creates one if it doesn't already exist.
* @api private
*/
Publisher.prototype.getClient = function() {
if (!this.client) {
this.client = dgram.createSocket('udp4');
}
return this.client;
};
/**
* Destroys the udp socket.
* @api private
*/
Publisher.prototype.destroyClient = function() {
if (this.client) {
this.client.close();
this.client = void 0;
}
};
module.exports = {
Publisher: Publisher
};