diff --git a/src/blob/generated/middleware/end.middleware.ts b/src/blob/generated/middleware/end.middleware.ts index 710e8deb8..40c1744cc 100644 --- a/src/blob/generated/middleware/end.middleware.ts +++ b/src/blob/generated/middleware/end.middleware.ts @@ -28,7 +28,7 @@ export default function endMiddleware( )}`, context.contextId ); - AzuriteTelemetryClient.TraceBlobRequest(context); + AzuriteTelemetryClient.TraceRequest(context); res.getBodyStream().end(); } diff --git a/src/blob/generated/middleware/error.middleware.ts b/src/blob/generated/middleware/error.middleware.ts index 080dd7250..d8676275f 100644 --- a/src/blob/generated/middleware/error.middleware.ts +++ b/src/blob/generated/middleware/error.middleware.ts @@ -1,3 +1,4 @@ +import { AzuriteTelemetryClient } from '../../../common/Telemetry'; import Context from '../Context'; import MiddlewareError from '../errors/MiddlewareError'; import IRequest from '../IRequest'; @@ -129,6 +130,7 @@ export default function errorMiddleware( context.contextId ); } + AzuriteTelemetryClient.TraceRequest(context); next(); } diff --git a/src/common/Telemetry.ts b/src/common/Telemetry.ts index 40e88d489..cd0f2878a 100644 --- a/src/common/Telemetry.ts +++ b/src/common/Telemetry.ts @@ -40,7 +40,7 @@ export class AzuriteTelemetryClient { private static isDebug = true; // change to false in production private static requestCollectPercentage = AzuriteTelemetryClient.isDebug ? 100 : 1; private static enableAppInsightLog = AzuriteTelemetryClient.isDebug? true : false; - private static cloudRole = AzuriteTelemetryClient.isDebug ? "AzuriteTest" : "Azurite_SchemaV1.0"; + private static cloudRole = AzuriteTelemetryClient.isDebug ? "AzuriteTest" : "Azurite_V1.0"; // 0 means send as soon as it's collected, use it in both debug and release mode, since set any other value will make Azurite exist slower private static requestMaxBatchSize = AzuriteTelemetryClient.isDebug ? 0 : 0; @@ -122,10 +122,10 @@ export class AzuriteTelemetryClient { if (telemetryClient !== undefined) { - telemetryClient.context.tags[telemetryClient.context.keys.cloudRole] = "AzuriteTest"; + telemetryClient.context.tags[telemetryClient.context.keys.cloudRole] = AzuriteTelemetryClient.cloudRole; } - telemetryClient.config.samplingPercentage = samplingPercentage??100; + telemetryClient.config.samplingPercentage = samplingPercentage??1; // Enable AppInsight log, should enable in develoipment only if (AzuriteTelemetryClient.enableAppInsightLog) @@ -140,18 +140,42 @@ export class AzuriteTelemetryClient { return telemetryClient; } - public static TraceBlobRequest(context: BlobContext) { + public static TraceRequest(context: any) { + let serviceType = ""; + let totalReqs = 0; + let reqName = ""; try{ if (AzuriteTelemetryClient.enableTelemetry && AzuriteTelemetryClient.requestClient !== undefined) { - AzuriteTelemetryClient._totalBlobRequestCount++; + if (context instanceof BlobContext) + { + serviceType = "Blob"; + AzuriteTelemetryClient._totalBlobRequestCount++; + totalReqs = AzuriteTelemetryClient._totalBlobRequestCount; + reqName = "B_" + BlobOperation[context.operation??0]; + } + else if (context instanceof QueueContext) + { + serviceType = "Queue"; + AzuriteTelemetryClient._totalQueueRequestCount++; + totalReqs = AzuriteTelemetryClient._totalQueueRequestCount; + reqName = "Q_" + QueueOperation[context.operation??0]; + } + else if (context instanceof TableContext) + { + serviceType = "Table"; + AzuriteTelemetryClient._totalTableRequestCount++; + totalReqs = AzuriteTelemetryClient._totalTableRequestCount; + reqName = "T_" + TableOperation[context.operation??0]; + } let requestProperties: { [key: string]: any } = { apiVersion: "v"+context.request?.getHeader("x-ms-version"), authorization: context.request !== undefined ? AzuriteTelemetryClient.GetRequestAuthentication(context.request.getHeader("authorization"), context.request.getQuery("sig")) : "", instanceID: AzuriteTelemetryClient.instanceID, sessionID: AzuriteTelemetryClient.sessionID, - totalReqs:AzuriteTelemetryClient._totalBlobRequestCount, + totalReqs:totalReqs, }; + // Responds "content-length" Not work, as responds normally don't have "content-length" header even has body. So will only collect ingress, but not collect egress if (context.request?.getHeader("content-length") !== undefined) { const contentLength = context.request?.getHeader("content-length"); @@ -160,15 +184,14 @@ export class AzuriteTelemetryClient { this._totalIngressSize += parseInt(contentLength); } } - // Responds "content-length" Not work, as responds normally don't have "content-length" header even has body. AzuriteTelemetryClient.requestClient.trackRequest( { - name:"B_" + BlobOperation[context.operation??0], + name:reqName, url:context.request !== undefined ? AzuriteTelemetryClient.GetRequestUri(context.request.getEndpoint()) : "", duration:context.startTime?((new Date()).getTime() - context.startTime?.getTime()):0, resultCode:context.response?.getStatusCode()??0, - success:context.response?.getStatusCode()?.toString().startsWith("2")??false, + success:"123".includes(context.response?.getStatusCode()?.toString()[0])??false, // Question: should we move InstanceID and SessionID to telemetry properties id & source, and move requestID and useragent to properties (customDimensions)? id: context.contextId, // Request ID source: context.request?.getHeader("user-agent"), // User Agent @@ -183,102 +206,102 @@ export class AzuriteTelemetryClient { } }); } - logger.verbose('Send blob telemetry: ' + BlobOperation[context.operation??0], context.contextId); + logger.verbose(`Send ${serviceType} telemetry: ` + reqName, context.contextId); } catch (e) { - logger.warn('Fail to telemetry a blob request, error: ' + e.message); + logger.warn(`Fail to telemetry a ${serviceType} request, error: ` + e.message); } } - public static TraceQueueRequest(context: QueueContext) { - try{ - if (AzuriteTelemetryClient.enableTelemetry && AzuriteTelemetryClient.requestClient !== undefined) - { - AzuriteTelemetryClient._totalQueueRequestCount++; - let requestProperties: { [key: string]: any } = { - apiVersion: "v"+context.request?.getHeader("x-ms-version"), - authorization: context.request !== undefined ? AzuriteTelemetryClient.GetRequestAuthentication(context.request.getHeader("authorization"), context.request.getQuery("sig")) : "", - instanceID: AzuriteTelemetryClient.instanceID, - sessionID: AzuriteTelemetryClient.sessionID, - totalReqs:AzuriteTelemetryClient._totalQueueRequestCount, - }; - if (context.request?.getHeader("content-length") !== undefined) - { - requestProperties["requestContentSize"] = context.request?.getHeader("content-length"); - } - // Responds "content-length" Not work, as responds normally don't have "content-length" header even has body. - AzuriteTelemetryClient.requestClient.trackRequest( - { - name:"Q_" + QueueOperation[context.operation??0], - url:context.request !== undefined ? AzuriteTelemetryClient.GetRequestUri(context.request.getEndpoint()) : "", - duration:context.startTime?((new Date()).getTime() - context.startTime?.getTime()):0, - resultCode:context.response?.getStatusCode()??0, - success:context.response?.getStatusCode()?.toString().startsWith("2")??false, - id: context.contextID, - source: context.request?.getHeader("user-agent"), - properties: requestProperties, - contextObjects: - { - operationId: "", - operationParentId: "", - operationName: "test", - operation_Name: "test", - appName: "" - } - }); - } - logger.verbose('Send queue telemetry: ' + QueueOperation[context.operation??0], context.contextID); - } - catch (e) - { - logger.warn('Fail to telemetry a queue request, error: ' + e.message); - } - } - - public static TraceTableRequest(context: TableContext) { - try{ - if (AzuriteTelemetryClient.enableTelemetry && AzuriteTelemetryClient.requestClient !== undefined) - { - AzuriteTelemetryClient._totalTableRequestCount++; - let requestProperties: { [key: string]: any } = { - apiVersion: "v"+context.request?.getHeader("x-ms-version"), - authorization: context.request !== undefined ? AzuriteTelemetryClient.GetRequestAuthentication(context.request.getHeader("authorization"), context.request.getQuery("sig")) : "", - instanceID: AzuriteTelemetryClient.instanceID, - sessionID: AzuriteTelemetryClient.sessionID, - totalReqs:AzuriteTelemetryClient._totalTableRequestCount, - }; - if (context.request?.getHeader("content-length") !== undefined) - { - requestProperties["requestContentSize"] = context.request?.getHeader("content-length"); - } - AzuriteTelemetryClient.requestClient.trackRequest( - { - name:"T_" + TableOperation[context.operation??0], - url:context.request !== undefined ? AzuriteTelemetryClient.GetRequestUri(context.request.getEndpoint()) : "", - duration:context.startTime?((new Date()).getTime() - context.startTime?.getTime()):0, - resultCode:context.response?.getStatusCode()??0, - success:context.response?.getStatusCode()?.toString().startsWith("2")??false, - id: context.contextID, - source: context.request?.getHeader("user-agent"), - properties: requestProperties, - contextObjects: - { - operationId: "", - operationParentId: "", - operationName: "test", - operation_Name: "test", - appName: "" - } - }); - } - logger.verbose('Send table telemetry: ' + TableOperation[context.operation??0], context.contextID); - } - catch (e) - { - logger.warn('Fail to telemetry a table request, error: ' + e.message); - } - } + // public static TraceQueueRequest(context: QueueContext) { + // try{ + // if (AzuriteTelemetryClient.enableTelemetry && AzuriteTelemetryClient.requestClient !== undefined) + // { + // AzuriteTelemetryClient._totalQueueRequestCount++; + // let requestProperties: { [key: string]: any } = { + // apiVersion: "v"+context.request?.getHeader("x-ms-version"), + // authorization: context.request !== undefined ? AzuriteTelemetryClient.GetRequestAuthentication(context.request.getHeader("authorization"), context.request.getQuery("sig")) : "", + // instanceID: AzuriteTelemetryClient.instanceID, + // sessionID: AzuriteTelemetryClient.sessionID, + // totalReqs:AzuriteTelemetryClient._totalQueueRequestCount, + // }; + // if (context.request?.getHeader("content-length") !== undefined) + // { + // requestProperties["requestContentSize"] = context.request?.getHeader("content-length"); + // } + // // Responds "content-length" Not work, as responds normally don't have "content-length" header even has body. + // AzuriteTelemetryClient.requestClient.trackRequest( + // { + // name:"Q_" + QueueOperation[context.operation??0], + // url:context.request !== undefined ? AzuriteTelemetryClient.GetRequestUri(context.request.getEndpoint()) : "", + // duration:context.startTime?((new Date()).getTime() - context.startTime?.getTime()):0, + // resultCode:context.response?.getStatusCode()??0, + // success:context.response?.getStatusCode()?.toString().startsWith("2")??false, + // id: context.contextID, + // source: context.request?.getHeader("user-agent"), + // properties: requestProperties, + // contextObjects: + // { + // operationId: "", + // operationParentId: "", + // operationName: "test", + // operation_Name: "test", + // appName: "" + // } + // }); + // } + // logger.verbose('Send queue telemetry: ' + QueueOperation[context.operation??0], context.contextID); + // } + // catch (e) + // { + // logger.warn('Fail to telemetry a queue request, error: ' + e.message); + // } + // } + + // public static TraceTableRequest(context: TableContext) { + // try{ + // if (AzuriteTelemetryClient.enableTelemetry && AzuriteTelemetryClient.requestClient !== undefined) + // { + // AzuriteTelemetryClient._totalTableRequestCount++; + // let requestProperties: { [key: string]: any } = { + // apiVersion: "v"+context.request?.getHeader("x-ms-version"), + // authorization: context.request !== undefined ? AzuriteTelemetryClient.GetRequestAuthentication(context.request.getHeader("authorization"), context.request.getQuery("sig")) : "", + // instanceID: AzuriteTelemetryClient.instanceID, + // sessionID: AzuriteTelemetryClient.sessionID, + // totalReqs:AzuriteTelemetryClient._totalTableRequestCount, + // }; + // if (context.request?.getHeader("content-length") !== undefined) + // { + // requestProperties["requestContentSize"] = context.request?.getHeader("content-length"); + // } + // AzuriteTelemetryClient.requestClient.trackRequest( + // { + // name:"T_" + TableOperation[context.operation??0], + // url:context.request !== undefined ? AzuriteTelemetryClient.GetRequestUri(context.request.getEndpoint()) : "", + // duration:context.startTime?((new Date()).getTime() - context.startTime?.getTime()):0, + // resultCode:context.response?.getStatusCode()??0, + // success:context.response?.getStatusCode()?.toString().startsWith("2")??false, + // id: context.contextID, + // source: context.request?.getHeader("user-agent"), + // properties: requestProperties, + // contextObjects: + // { + // operationId: "", + // operationParentId: "", + // operationName: "test", + // operation_Name: "test", + // appName: "" + // } + // }); + // } + // logger.verbose('Send table telemetry: ' + TableOperation[context.operation??0], context.contextID); + // } + // catch (e) + // { + // logger.warn('Fail to telemetry a table request, error: ' + e.message); + // } + // } public static async TraceStartEvent(serviceType: string = "") { try{ @@ -337,15 +360,6 @@ export class AzuriteTelemetryClient { { return endpoint; } - - // let request = context.request; - // let requestUri = request.getUrl(); - // let sig = request.getQuery("sig"); - // if (sig!=undefined) - // { - // requestUri = requestUri.replace(encodeURIComponent(sig), "[hidden]"); - // } - // return `${request.getEndpoint()}${requestUri}`; } @@ -364,32 +378,35 @@ export class AzuriteTelemetryClient { if(!fs.existsSync(configFilePath)) { instaceID = uuid(); - fs.writeFile(configFilePath, `{"instaceID":"${instaceID}"}`, (err) => { - logger.warn('Fail to save instaceID, error: ' + err?.message); - }); + // fs.writeFile(configFilePath, `{"instaceID":"${instaceID}"}`, (err) => { + // logger.warn('Fail to save instaceID, error: ' + err?.message); + // }); + fs.writeFileSync(configFilePath, `{"instaceID":"${instaceID}"}`); } else{ let data = fs.readFileSync(configFilePath, 'utf8'); instaceID = JSON.parse(data.toString()).instaceID; - if(instaceID === "") + if(instaceID === undefined || instaceID === "") { instaceID = uuid(); - fs.writeFile(configFilePath, instaceID, (err) => { - logger.warn('Fail to save instaceID, error: ' + err?.message); - }); + // fs.writeFile(configFilePath, instaceID, (err) => { + // logger.warn('Fail to save instaceID, error: ' + err?.message); + // }); + fs.writeFileSync(configFilePath, `{"instaceID":"${instaceID}"}`); } } return instaceID; } catch (e) { - logger.warn('Fail to generate and save instaceID will use empty instaceID, error: ' + e.message); + logger.warn('Fail to generate read or save instaceID will use empty instaceID, error: ' + e.message); return instaceID; } } private static GetRequestAuthentication(authorizationHeader: string|undefined, sigQuery: string|undefined): string { + // TODO: support combined auth type like Oauth + SAS let auth = authorizationHeader?.split(" ")[0]; - if (auth === undefined) + if (auth === undefined || auth === "") { if (sigQuery !== undefined) { diff --git a/src/queue/generated/middleware/end.middleware.ts b/src/queue/generated/middleware/end.middleware.ts index 402ace575..13dcb7756 100644 --- a/src/queue/generated/middleware/end.middleware.ts +++ b/src/queue/generated/middleware/end.middleware.ts @@ -28,7 +28,7 @@ export default function endMiddleware( )}`, context.contextID ); - AzuriteTelemetryClient.TraceQueueRequest(context); + AzuriteTelemetryClient.TraceRequest(context); res.getBodyStream().end(); } diff --git a/src/queue/generated/middleware/error.middleware.ts b/src/queue/generated/middleware/error.middleware.ts index e923e0c65..cb8f64173 100644 --- a/src/queue/generated/middleware/error.middleware.ts +++ b/src/queue/generated/middleware/error.middleware.ts @@ -1,3 +1,4 @@ +import { AzuriteTelemetryClient } from "../../../common/Telemetry"; import Context from "../Context"; import MiddlewareError from "../errors/MiddlewareError"; import IRequest from "../IRequest"; @@ -129,6 +130,7 @@ export default function errorMiddleware( context.contextID ); } + AzuriteTelemetryClient.TraceRequest(context) ; next(); } diff --git a/src/table/generated/middleware/end.middleware.ts b/src/table/generated/middleware/end.middleware.ts index d2ec9047c..f7ec7addc 100644 --- a/src/table/generated/middleware/end.middleware.ts +++ b/src/table/generated/middleware/end.middleware.ts @@ -28,7 +28,7 @@ export default function endMiddleware( )}`, context.contextID ); - AzuriteTelemetryClient.TraceTableRequest(context) ; + AzuriteTelemetryClient.TraceRequest(context) ; res.getBodyStream().end(); } diff --git a/src/table/generated/middleware/error.middleware.ts b/src/table/generated/middleware/error.middleware.ts index 696788b04..83087532b 100644 --- a/src/table/generated/middleware/error.middleware.ts +++ b/src/table/generated/middleware/error.middleware.ts @@ -1,3 +1,4 @@ +import { AzuriteTelemetryClient } from "../../../common/Telemetry"; import Context from "../Context"; import MiddlewareError from "../errors/MiddlewareError"; import IRequest from "../IRequest"; @@ -126,6 +127,7 @@ export default function errorMiddleware( context.contextID ); } + AzuriteTelemetryClient.TraceRequest(context) ; next(); } diff --git a/tests/BlobTestServerFactory.ts b/tests/BlobTestServerFactory.ts index 9eaa63925..84d56a08b 100644 --- a/tests/BlobTestServerFactory.ts +++ b/tests/BlobTestServerFactory.ts @@ -79,7 +79,6 @@ export default class BlobTestServerFactory { undefined, inMemoryPersistence ); - AzuriteTelemetryClient.init("", true, undefined); return new BlobServer(config); } } diff --git a/tests/blob/blobCorsRequest.test.ts b/tests/blob/blobCorsRequest.test.ts index 143d97857..edfddd96e 100644 --- a/tests/blob/blobCorsRequest.test.ts +++ b/tests/blob/blobCorsRequest.test.ts @@ -42,6 +42,7 @@ describe("Blob Cors requests test", () => { before(async () => { await server.start(); + AzuriteTelemetryClient.init("", true, undefined); await AzuriteTelemetryClient.TraceStartEvent("Blob Test"); }); diff --git a/tests/queue/oauth.test.ts b/tests/queue/oauth.test.ts index 176391cab..6c34841df 100644 --- a/tests/queue/oauth.test.ts +++ b/tests/queue/oauth.test.ts @@ -42,6 +42,7 @@ describe("Queue OAuth Basic", () => { oauth: "basic" }) await server.start(); + AzuriteTelemetryClient.init("", true, undefined); await AzuriteTelemetryClient.TraceStartEvent("Queue Test"); }); diff --git a/tests/queue/utils/QueueTestServerFactory.ts b/tests/queue/utils/QueueTestServerFactory.ts index 7d541a8f3..c4a37c9c7 100644 --- a/tests/queue/utils/QueueTestServerFactory.ts +++ b/tests/queue/utils/QueueTestServerFactory.ts @@ -46,7 +46,6 @@ export default class QueueTestServerFactory { undefined, inMemoryPersistence ); - AzuriteTelemetryClient.init("", true, undefined); return new QueueServer(config); } } diff --git a/tests/table/apis/table.entity.azure.data-tables.test.ts b/tests/table/apis/table.entity.azure.data-tables.test.ts index a4d8ef0b0..552b32b40 100644 --- a/tests/table/apis/table.entity.azure.data-tables.test.ts +++ b/tests/table/apis/table.entity.azure.data-tables.test.ts @@ -39,6 +39,7 @@ describe("table Entity APIs test - using Azure/data-tables", () => { before(async () => { server = createTableServerForTestHttps(); await server.start(); + AzuriteTelemetryClient.init("", true, undefined); await AzuriteTelemetryClient.TraceStartEvent("Table Test"); }); diff --git a/tests/table/utils/TableTestServerFactory.ts b/tests/table/utils/TableTestServerFactory.ts index d4c05239a..fa6ecc7bd 100644 --- a/tests/table/utils/TableTestServerFactory.ts +++ b/tests/table/utils/TableTestServerFactory.ts @@ -45,7 +45,6 @@ export default class TableTestServerFactory { undefined, inMemoryPersistence ); - AzuriteTelemetryClient.init("", true, undefined); return new TableServer(config); } }