UNPKG

@newrelic/newrelic-capacitor-plugin

Version:
500 lines (491 loc) 20.4 kB
var capacitorNewRelicCapacitorPlugin = (function (exports, core) { 'use strict'; /** * Source: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Cyclic_object_value * Any copyright is dedicated to the Public Domain: https://creativecommons.org/publicdomain/zero/1.0/ */ const getCircularReplacer = () => { const seen = new WeakSet(); return (_key, value) => { if (typeof value === "object" && value !== null) { if (seen.has(value)) { return; } seen.add(value); } return value; }; }; /* * Copyright (c) 2022-present New Relic Corporation. All rights reserved. * SPDX-License-Identifier: Apache-2.0 */ exports.NREnums = void 0; (function (NREnums) { (function (LogLevel) { LogLevel["ERROR"] = "ERROR"; LogLevel["WARNING"] = "WARNING"; LogLevel["INFO"] = "INFO"; LogLevel["VERBOSE"] = "VERBOSE"; LogLevel["AUDIT"] = "AUDIT"; })(NREnums.LogLevel || (NREnums.LogLevel = {})); (function (NetworkFailure) { NetworkFailure["Unknown"] = "Unknown"; NetworkFailure["BadURL"] = "BadURL"; NetworkFailure["TimedOut"] = "TimedOut"; NetworkFailure["CannotConnectToHost"] = "CannotConnectToHost"; NetworkFailure["DNSLookupFailed"] = "DNSLookupFailed"; NetworkFailure["BadServerResponse"] = "BadServerResponse"; NetworkFailure["SecureConnectionFailed"] = "SecureConnectionFailed"; })(NREnums.NetworkFailure || (NREnums.NetworkFailure = {})); (function (MetricUnit) { MetricUnit["PERCENT"] = "PERCENT"; MetricUnit["BYTES"] = "BYTES"; MetricUnit["SECONDS"] = "SECONDS"; MetricUnit["BYTES_PER_SECOND"] = "BYTES_PER_SECOND"; MetricUnit["OPERATIONS"] = "OPERATIONS"; })(NREnums.MetricUnit || (NREnums.MetricUnit = {})); })(exports.NREnums || (exports.NREnums = {})); /* * Copyright (c) 2022-present New Relic Corporation. All rights reserved. * SPDX-License-Identifier: Apache-2.0 */ const NewRelicCapacitorPlugin = core.registerPlugin('NewRelicCapacitorPlugin', { web: () => Promise.resolve().then(function () { return web; }).then(m => new m.NewRelicCapacitorPluginWeb()) }); const defaultLog = window.console.log; const defaultWarn = window.console.warn; const defaultError = window.console.error; const defaultAssert = window.console.assert; const defaultDebug = window.console.debug; console.log = function () { var msgs = []; defaultLog(...arguments); while (arguments.length) { var copyArguments = Object.assign({}, arguments); msgs.push('[]' + ': ' + [].shift.call(arguments)); sendConsole('log', copyArguments); } }; console.warn = function () { var msgs = []; defaultWarn(...arguments); while (arguments.length) { var copyArguments = Object.assign({}, arguments); msgs.push('[]' + ': ' + [].shift.call(arguments)); sendConsole('warn', copyArguments); } }; console.error = function () { var msgs = []; defaultError(...arguments); while (arguments.length) { var copyArguments = Object.assign({}, arguments); msgs.push('[]' + ': ' + [].shift.call(arguments)); sendConsole('error', copyArguments); } }; console.assert = function () { var msgs = []; defaultAssert(...arguments); while (arguments.length) { var copyArguments = Object.assign({}, arguments); msgs.push('[]' + ': ' + [].shift.call(arguments)); sendConsole('assert', copyArguments); } }; console.debug = function () { var msgs = []; defaultDebug(...arguments); while (arguments.length) { var copyArguments = Object.assign({}, arguments); msgs.push('[]' + ': ' + [].shift.call(arguments)); sendConsole('debug', copyArguments); } }; function sendConsole(consoleType, _arguments) { NewRelicCapacitorPlugin.getAgentConfiguration().then((agentConfig) => { if (agentConfig.sendConsoleEvents) { const argsStr = JSON.stringify(_arguments, getCircularReplacer()); if (consoleType === 'error') { NewRelicCapacitorPlugin.logError({ message: `[CONSOLE][ERROR]${argsStr}` }); } else if (consoleType === 'warn') { NewRelicCapacitorPlugin.logWarning({ message: `[CONSOLE][WARN]${argsStr}` }); } else if (consoleType === 'debug') { NewRelicCapacitorPlugin.logDebug({ message: `[CONSOLE][DEBUG]${argsStr}` }); } else { NewRelicCapacitorPlugin.logInfo({ message: `[CONSOLE][LOG]${argsStr}` }); } } }); } window.addEventListener('error', event => { NewRelicCapacitorPlugin.recordError({ name: event.error.name, message: event.error.message, stack: event.error.stack, isFatal: true, }); }); window.addEventListener('unhandledrejection', e => { var err = new Error(e.reason); NewRelicCapacitorPlugin.recordError({ name: err.name, message: err.message, stack: 'no stack', isFatal: false, }); }); const networkRequest = { url: "", method: "", body: "", bytesSent: 0, startTime: 0, headers: [], params: {} }; const oldFetch = window.fetch; window.fetch = function fetch() { var _arguments = arguments; var urlOrRequest = arguments[0]; var options = arguments[1]; return NewRelicCapacitorPlugin.getHTTPHeadersTrackingFor().then((trackingHeadersList) => { console.log(trackingHeadersList); return NewRelicCapacitorPlugin.generateDistributedTracingHeaders().then((headers) => { networkRequest.startTime = Date.now(); if (urlOrRequest && typeof urlOrRequest === 'object') { networkRequest.url = urlOrRequest.url; if (options && 'method' in options) { networkRequest.method = options.method; } else if (urlOrRequest && 'method' in urlOrRequest) { networkRequest.method = urlOrRequest.method; } } else { networkRequest.url = urlOrRequest; if (options && 'method' in options) { networkRequest.method = options.method; } } return NewRelicCapacitorPlugin.getAgentConfiguration().then((agentConfig) => { if (options && 'headers' in options) { if (agentConfig.distributedTracingEnabled) { options.headers['newrelic'] = headers['newrelic']; options.headers['traceparent'] = headers['traceparent']; options.headers['tracestate'] = headers['tracestate']; } JSON.parse(trackingHeadersList["headersList"]).forEach((e) => { if (options.headers[e] !== undefined) { networkRequest.params[e] = options.headers[e]; } }); } else { if (options === undefined) { options = {}; } if (agentConfig.distributedTracingEnabled) { options['headers'] = {}; options.headers['newrelic'] = headers['newrelic']; options.headers['traceparent'] = headers['traceparent']; options.headers['tracestate'] = headers['tracestate']; } _arguments[1] = options; } if (!agentConfig.distributedTracingEnabled) { headers = {}; } if (options && 'body' in options && options.body !== null && options.body !== undefined) { networkRequest.bytesSent = options.body.length; } else { networkRequest.bytesSent = 0; } if (networkRequest.method === undefined || networkRequest.method === "") { networkRequest.method = 'GET'; } return new Promise(function (resolve, reject) { // pass through to native fetch oldFetch.apply(void 0, _arguments).then(function (response) { handleFetchSuccess(response.clone(), networkRequest.method, networkRequest.url, networkRequest.startTime, headers, networkRequest.params); resolve(response); })["catch"](function (error) { reject(error); }); }); }); }); }); }; const originalXhrOpen = XMLHttpRequest.prototype.open; const originalXhrSend = XMLHttpRequest.prototype.send; window.XMLHttpRequest.prototype.open = function (method, url) { networkRequest.url = url; networkRequest.method = method; networkRequest.bytesSent = 0; networkRequest.startTime = Date.now(); return originalXhrOpen.apply(this, arguments); }; window.XMLHttpRequest.prototype.send = function () { if (this.addEventListener) { this.addEventListener("readystatechange", async () => { if (this.readyState === this.OPENED) ; if (this.readyState === this.HEADERS_RECEIVED) { if (this.getAllResponseHeaders()) { const responseHeaders = this.getAllResponseHeaders().split("\r\n"); responseHeaders.forEach((element) => { element.split(":")[0]; element.split(":")[1]; }); } } if (this.readyState === this.DONE) { networkRequest.endTime = Date.now(); networkRequest.status = this.status; const type = this.responseType; if (type === "arraybuffer") { networkRequest.bytesreceived = this.response.byteLength; } else if (type === "blob") { networkRequest.bytesreceived = this.response.size; } else if (type === "text" || type === "" || type === undefined) { networkRequest.bytesreceived = this.responseText.length; networkRequest.body = this.responseText; } else { // unsupported response type networkRequest.bytesreceived = 0; } if (isValidURL(networkRequest.url)) { NewRelicCapacitorPlugin.noticeHttpTransaction({ url: networkRequest.url, method: networkRequest.method, status: networkRequest.status, startTime: networkRequest.startTime, endTime: networkRequest.endTime, bytesSent: networkRequest.bytesSent, bytesReceived: networkRequest.bytesreceived, body: networkRequest.body, traceAttributes: networkRequest.headers, params: networkRequest.params }); } } }, false); } return originalXhrSend.apply(this, arguments); }; function handleFetchSuccess(response, method, url, startTime, traceAttributes, params) { response.text().then((v) => { if (isValidURL(url)) { NewRelicCapacitorPlugin.noticeHttpTransaction({ url: url, method: method, status: response.status, startTime: startTime, endTime: Date.now(), bytesSent: networkRequest.bytesSent, bytesReceived: v.length, body: v, traceAttributes: traceAttributes, params: params }); } }); } function isValidURL(url) { try { const newUrl = new URL(url); return newUrl.protocol === 'http:' || newUrl.protocol === 'https:'; } catch (err) { return false; } } class NewRelicCapacitorPluginWeb extends core.WebPlugin { start(_options) { // throw new Error('Method not implemented.'); } setUserId(_options) { //throw new Error('Method not implemented.'); } setAttribute(_options) { //throw new Error('Method not implemented.'); } removeAttribute(_options) { //throw new Error('Method not implemented.'); } recordBreadcrumb(_options) { // throw new Error('Method not implemented.'); } recordCustomEvent(_options) { // throw new Error('Method not implemented.'); } startInteraction(_options) { return new Promise((resolve) => { resolve({ value: '' }); }); } endInteraction(_options) { // throw new Error('Method not implemented.'); } crashNow(_options) { //throw new Error('Method not implemented.'); } currentSessionId(_options) { //throw new Error('Method not implemented.'); return new Promise((resolve) => { resolve({ sessionId: '' }); }); } incrementAttribute(_options) { // throw new Error('Method not implemented.'); } noticeNetworkFailure(_options) { // throw new Error('Method not implemented.'); } noticeHttpTransaction(_options) { // throw new Error('Method not implemented.'); } recordMetric(_options) { // throw new Error('Method not implemented.'); } removeAllAttributes(_options) { // throw new Error('Method not implemented.'); } setMaxEventBufferTime(_options) { // throw new Error('Method not implemented.'); } setMaxEventPoolSize(_options) { // throw new Error('Method not implemented.'); } setMaxOfflineStorageSize(_options) { // throw new Error('Method not implemented.'); } recordError(_options) { // throw new Error('Method not implemented.'); } analyticsEventEnabled(_options) { // throw new Error('Method not implemented.'); } networkRequestEnabled(_options) { // throw new Error('Method not implemented.'); } networkErrorRequestEnabled(_options) { // throw new Error('Method not implemented.'); } httpResponseBodyCaptureEnabled(_options) { // throw new Error('Method not implemented.'); } getAgentConfiguration(_options) { let a = { analyticsEventEnabled: true, crashReportingEnabled: true, interactionTracingEnabled: true, networkRequestEnabled: true, networkErrorRequestEnabled: true, httpResponseBodyCaptureEnabled: true, webViewInstrumentation: true, loggingEnabled: true, logLevel: '', collectorAddress: '', crashCollectorAddress: '', sendConsoleEvents: true, fedRampEnabled: false, offlineStorageEnabled: true, distributedTracingEnabled: false, }; return new Promise((resolve) => { resolve(a); }); } shutdown(_options) { // throw new Error('Method not implemented.'); } generateDistributedTracingHeaders(_options) { let dtHeaders = { newrelic: "1", traceparent: "1", tracestate: "1", traceid: "1", guid: "1", id: "1" }; return new Promise((resolve) => { resolve(dtHeaders); }); // throw new Error('Method not implemented.'); } addHTTPHeadersTrackingFor(_options) { // throw new Error('Method not implemented.'); } log(_options) { if (_options.message === undefined || _options.message.length === 0) { // If the message is empty, log an error message and return console.error("Log message is empty."); return; } // Create a new Map to store attributes let attributes = new Map(); // Set the message and log level as attributes attributes.set("message", _options.message); attributes.set("level", _options.level); // Log the attributes this.logAttributes({ attributes: attributes }); } logError(_options) { this.log({ level: exports.NREnums.LogLevel.ERROR, message: _options.message }); } logWarning(_options) { this.log({ level: exports.NREnums.LogLevel.WARNING, message: _options.message }); } logAll(_options) { let allAttributes = new Map(); // Set the error message as an attribute allAttributes.set("message", _options.error); // Iterate over the attributes Map and add each attribute to allAttributes for (let [key, value] of Object.entries(_options.attributes)) { allAttributes.set(key, value); } // Log all attributes this.logAttributes({ attributes: allAttributes }); } logInfo(_options) { this.log({ level: exports.NREnums.LogLevel.INFO, message: _options.message }); } logVerbose(_options) { this.log({ level: exports.NREnums.LogLevel.VERBOSE, message: _options.message }); } logDebug(_options) { this.log({ level: exports.NREnums.LogLevel.AUDIT, message: _options.message }); } logAttributes(_options) { if (_options.attributes === undefined || _options.attributes.size === 0) { // If the attributes are empty, log an error message and return console.error("Attributes are empty."); return; } } getHTTPHeadersTrackingFor() { let httpHeadersTracking = { headersList: "[]" }; return new Promise((resolve) => { resolve(httpHeadersTracking); }); } } var web = /*#__PURE__*/Object.freeze({ __proto__: null, NewRelicCapacitorPluginWeb: NewRelicCapacitorPluginWeb }); exports.NewRelicCapacitorPlugin = NewRelicCapacitorPlugin; return exports; })({}, capacitorExports); //# sourceMappingURL=plugin.js.map