o11y 238.7.0 → 240.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (25) hide show
  1. package/dist/modules/o11y/client/client.js +173 -75
  2. package/dist/modules/o11y/client/client.js.map +1 -1
  3. package/dist/modules/o11y/client/interfaces/ActivityApiOptions.d.ts +6 -0
  4. package/dist/modules/o11y/client/interfaces/Instrumentation.d.ts +3 -0
  5. package/dist/modules/o11y/client/interfaces/index.d.ts +1 -0
  6. package/dist/modules/o11y/client/library/InstrumentationImpl.d.ts +5 -1
  7. package/dist/modules/o11y/client/library/LogValidator.d.ts +25 -1
  8. package/dist/modules/o11y/collectors/collectors.js +1 -1
  9. package/dist/modules/o11y/collectors/collectors.js.map +1 -1
  10. package/dist/modules/o11y/collectors/interfaces/ActivityApiOptions.d.ts +6 -0
  11. package/dist/modules/o11y/collectors/interfaces/Instrumentation.d.ts +3 -0
  12. package/dist/modules/o11y/collectors/interfaces/index.d.ts +1 -0
  13. package/dist/modules/o11y/collectors/library/InstrumentationImpl.d.ts +5 -1
  14. package/dist/modules/o11y/collectors/library/LogValidator.d.ts +25 -1
  15. package/dist/modules/o11y/shared/interfaces/ActivityApiOptions.d.ts +6 -0
  16. package/dist/modules/o11y/shared/interfaces/Instrumentation.d.ts +3 -0
  17. package/dist/modules/o11y/shared/interfaces/index.d.ts +1 -0
  18. package/dist/modules/o11y/shared/library/InstrumentationImpl.d.ts +5 -1
  19. package/dist/modules/o11y/shared/library/LogValidator.d.ts +25 -1
  20. package/dist/modules/o11y/web_vitals/interfaces/ActivityApiOptions.d.ts +6 -0
  21. package/dist/modules/o11y/web_vitals/interfaces/Instrumentation.d.ts +3 -0
  22. package/dist/modules/o11y/web_vitals/interfaces/index.d.ts +1 -0
  23. package/dist/modules/o11y/web_vitals/library/InstrumentationImpl.d.ts +5 -1
  24. package/dist/modules/o11y/web_vitals/library/LogValidator.d.ts +25 -1
  25. package/package.json +2 -2
@@ -291,7 +291,9 @@ class ActivityImpl {
291
291
  const stopPerfTime = utility.perfNow();
292
292
  if (this._usePerf) {
293
293
  try {
294
- performance.measure(this._perfName, this._perfId);
294
+ if (this._stopReason !== stopReason.discarded) {
295
+ performance.measure(this._perfName, this._perfId);
296
+ }
295
297
  performance.clearMarks(this._perfId);
296
298
  performance.clearMeasures(this._perfName);
297
299
  }
@@ -447,136 +449,170 @@ class DomEventHelpers {
447
449
  const singleton = new DomEventHelpers();
448
450
  const domEventHelpers = singleton;
449
451
 
450
- const maxFieldLength = 10000;
451
- const minFieldLength = 0;
452
- const maxFourBytesPos = 2147483647;
453
- const maxFourBytesNeg = -2147483648;
452
+ const maxStringLengthAppLimit = 10000;
453
+ const maxItemCountAppLimit = 10000;
454
+ const minUnsigned = 0;
455
+ const maxFourBytes = 2147483647;
456
+ const minFourBytes = -2147483648;
454
457
  const maxFourBytesUnsigned = 4294967295;
455
- const maxEightBytesPos = 9223372036854776000;
456
- const maxEightBytesNeg = -9223372036854776001;
458
+ const maxEightBytes = 9223372036854776000;
459
+ const minEightBytes = -9223372036854776001;
457
460
  const maxEightBytesUnsigned = 18446744073709552000;
461
+ class ValidationEntry {
462
+ constructor(errorCode, fields, expected, received) {
463
+ this.errorCode = errorCode;
464
+ this.fields = fields;
465
+ this.expected = expected;
466
+ this.received = received;
467
+ }
468
+ asMessage(schemaId) {
469
+ const key = this.fields[0] +
470
+ this.fields
471
+ .slice(1)
472
+ .reduce((prev, current) => Number(current) >= 0 ? `${prev}[${current}]` : `${prev}.${current}`, '');
473
+ let msg;
474
+ switch (this.errorCode) {
475
+ case 1:
476
+ msg = 'Repeated field must be an array';
477
+ break;
478
+ case 2:
479
+ msg = `Expected type ${this.expected} but received type ${this.received}`;
480
+ break;
481
+ case 3:
482
+ msg = 'Value must be finite';
483
+ break;
484
+ case 4:
485
+ msg = 'Value is out of range for its type';
486
+ break;
487
+ case 5:
488
+ msg = 'Bytes array is malformed';
489
+ break;
490
+ case 6:
491
+ msg = 'Exceeded app limit for maximum string length';
492
+ break;
493
+ case 7:
494
+ msg = 'Exceeded app limit for item count';
495
+ break;
496
+ default:
497
+ msg = `Unknown error code: ${this.errorCode}`;
498
+ break;
499
+ }
500
+ return `Schema ${schemaId} on field "${key}": ${msg}`;
501
+ }
502
+ }
458
503
  class LogValidator {
459
- validate(schema, data) {
504
+ validate(schema, data, noThrow = false) {
460
505
  const schemaTokens = schemaUtil.checkSchema(schema);
461
506
  utility.requireArgument(data, 'data', 'object');
507
+ const schemaId = schemaUtil.getSchemaId(schema);
508
+ const errorInfos = new Array();
462
509
  const nestedSchema = schemaUtil.getTypes(schema);
463
- const errorMessage = this.validateFields(data, nestedSchema[schemaTokens.message], nestedSchema, schemaUtil.getSchemaId(schema));
464
- if (errorMessage) {
465
- throw new Error(errorMessage);
510
+ this.validateFields(errorInfos, [], data, nestedSchema[schemaTokens.message], nestedSchema, schemaId);
511
+ if (errorInfos.length && !noThrow) {
512
+ throw new Error(errorInfos[0].asMessage(schemaId));
466
513
  }
514
+ return errorInfos;
467
515
  }
468
- validateFields(data, message, custom, schemaId) {
516
+ validateFields(errorInfos, fieldNames, data, message, descriptor, schemaId) {
469
517
  const oneofs = message.oneofs || {};
470
518
  const fields = message.fields || {};
471
- let errorMessage = undefined;
472
519
  for (const key in data) {
473
520
  const value = data[key];
474
521
  if (!this.isNullOrUndefinedOrEmpty(value)) {
522
+ const mft = (fieldType, rule) => this.matchFieldTypes(errorInfos, [...fieldNames, key], value, fieldType, descriptor, schemaId, key, rule);
475
523
  if (oneofs[key]) {
476
- errorMessage = this.matchFieldTypes(value, oneofs[key].oneof[0], custom, schemaId, key);
524
+ mft(fields[oneofs[key].oneof[0]].type);
477
525
  }
478
526
  else if (fields[key]) {
479
- errorMessage = this.matchFieldTypes(value, fields[key].type, custom, schemaId, key, fields[key].rule);
527
+ mft(fields[key].type, fields[key].rule);
480
528
  }
481
529
  }
482
- if (errorMessage) {
483
- return errorMessage;
484
- }
485
530
  }
486
- return undefined;
487
531
  }
488
532
  isNullOrUndefinedOrEmpty(val) {
489
533
  return val === undefined || val === null || val === '';
490
534
  }
491
- matchFieldTypes(fieldData, fieldType, descriptor, schemaId, key, rule) {
492
- let convertedSchemaType;
493
- let extraContext = undefined;
535
+ matchFieldTypes(errorInfos, fieldNames, fieldDataValue, protobufType, descriptor, schemaId, key, rule) {
536
+ let errorCode;
494
537
  if (rule === 'repeated') {
495
- let errorMessage = undefined;
496
- if (Array.isArray(fieldData)) {
497
- for (const index in fieldData) {
498
- errorMessage = this.matchFieldTypes(fieldData[index], fieldType, descriptor, schemaId, key);
499
- if (errorMessage) {
500
- break;
501
- }
538
+ if (Array.isArray(fieldDataValue)) {
539
+ if (fieldDataValue.length > maxItemCountAppLimit) {
540
+ errorCode = 7;
541
+ }
542
+ for (const arrayKey in fieldDataValue) {
543
+ this.matchFieldTypes(errorInfos, [...fieldNames, arrayKey], fieldDataValue[arrayKey], protobufType, descriptor, schemaId, key);
502
544
  }
503
545
  }
504
546
  else {
505
- errorMessage = `Schema ${schemaId} on field: ${key}, repeated field should be an array`;
547
+ errorCode = 1;
548
+ }
549
+ if (errorCode) {
550
+ errorInfos.push(new ValidationEntry(errorCode, fieldNames));
506
551
  }
507
- return errorMessage;
552
+ return;
508
553
  }
509
- switch (fieldType) {
554
+ let javaScriptType;
555
+ switch (protobufType) {
510
556
  case 'string':
511
- convertedSchemaType = 'string';
557
+ javaScriptType = 'string';
558
+ if (fieldDataValue.length > maxStringLengthAppLimit) {
559
+ errorCode = 6;
560
+ }
512
561
  break;
513
562
  case 'bytes':
514
- convertedSchemaType = 'object';
515
- if (!(fieldData instanceof Uint8Array)) {
516
- extraContext = `Schema ${schemaId} on field: ${key}, bytes array is malformed`;
563
+ javaScriptType = 'object';
564
+ if (!(fieldDataValue instanceof Uint8Array)) {
565
+ errorCode = 5;
517
566
  }
518
567
  break;
519
568
  case 'bool':
520
- convertedSchemaType = 'boolean';
569
+ javaScriptType = 'boolean';
521
570
  break;
522
571
  case 'uint32':
523
- convertedSchemaType = 'number';
524
- extraContext = this.checkNumberRange(fieldData, maxFourBytesUnsigned, 0, schemaId, key);
572
+ javaScriptType = 'number';
573
+ errorCode = this.checkNumberRange(fieldDataValue, minUnsigned, maxFourBytesUnsigned);
525
574
  break;
526
575
  case 'int32':
527
576
  case 'sint32':
528
577
  case 'fixed32':
529
578
  case 'sfixed32':
530
- convertedSchemaType = 'number';
531
- extraContext = this.checkNumberRange(fieldData, maxFourBytesPos, maxFourBytesNeg, schemaId, key);
579
+ javaScriptType = 'number';
580
+ errorCode = this.checkNumberRange(fieldDataValue, minFourBytes, maxFourBytes);
532
581
  break;
533
582
  case 'uint64':
534
- convertedSchemaType = 'number';
535
- extraContext = this.checkNumberRange(fieldData, maxEightBytesUnsigned, 0, schemaId, key);
583
+ javaScriptType = 'number';
584
+ errorCode = this.checkNumberRange(fieldDataValue, minUnsigned, maxEightBytesUnsigned);
536
585
  break;
537
586
  case 'fixed64':
538
587
  case 'sfixed64':
539
588
  case 'int64':
540
589
  case 'sint64':
541
- convertedSchemaType = 'number';
542
- extraContext = this.checkNumberRange(fieldData, maxEightBytesPos, maxEightBytesNeg, schemaId, key);
590
+ javaScriptType = 'number';
591
+ errorCode = this.checkNumberRange(fieldDataValue, minEightBytes, maxEightBytes);
543
592
  break;
544
593
  case 'double':
545
594
  case 'float':
546
- convertedSchemaType = 'number';
547
- if (!Number.isFinite(fieldData)) {
548
- extraContext = `Schema ${schemaId} on field: ${key}. Value must be finite`;
595
+ javaScriptType = 'number';
596
+ if (!Number.isFinite(fieldDataValue)) {
597
+ errorCode = 3;
549
598
  }
550
599
  break;
551
600
  default:
552
- const ref = {};
553
- const keys = Object.keys(descriptor);
554
- for (const x in keys) {
555
- ref[keys[x].toLowerCase()] = keys[x];
556
- }
557
- if (ref[fieldType.toLowerCase()]) {
558
- extraContext = this.validateFields(fieldData, descriptor[ref[fieldType.toLowerCase()]], descriptor, schemaId);
559
- convertedSchemaType = 'object';
601
+ if (new Set(Object.keys(descriptor)).has(protobufType)) {
602
+ this.validateFields(errorInfos, fieldNames, fieldDataValue, descriptor[protobufType], descriptor, schemaId);
603
+ javaScriptType = 'object';
560
604
  }
561
605
  break;
562
606
  }
563
- const fieldLength = (fieldData + '').length;
564
- if (typeof fieldData !== convertedSchemaType) {
565
- return `Schema ${schemaId} on field: ${key}. Expected type ${fieldType} but received type ${typeof fieldData}`;
607
+ if (typeof fieldDataValue !== javaScriptType) {
608
+ errorInfos.push(new ValidationEntry(2, fieldNames, protobufType, typeof fieldDataValue));
566
609
  }
567
- else if (fieldLength < minFieldLength || fieldLength > maxFieldLength) {
568
- return `Schema ${schemaId} on field: ${key}, exceeded maximum or minimum field length`;
610
+ if (errorCode) {
611
+ errorInfos.push(new ValidationEntry(errorCode, fieldNames));
569
612
  }
570
- else if (extraContext) {
571
- return extraContext;
572
- }
573
- return undefined;
574
613
  }
575
- checkNumberRange(value, max, min, schemaId, key) {
576
- if (value > max || value < min) {
577
- return `Schema ${schemaId} on field: ${key}, number value is too large or small`;
578
- }
579
- return undefined;
614
+ checkNumberRange(value, min, max) {
615
+ return value > max || value < min ? 4 : undefined;
580
616
  }
581
617
  }
582
618
  const logValidator = new LogValidator();
@@ -883,7 +919,7 @@ class InstrumentationImpl {
883
919
  const simpleTextOptions = schemaUtil.getOptions(simple, 'Simple', 'text');
884
920
  this._simpleTextMaxLength = simpleTextOptions
885
921
  ? simpleTextOptions['(meta.max_length)']
886
- : Number.MAX_VALUE;
922
+ : maxStringLengthAppLimit;
887
923
  }
888
924
  _initMetrics() {
889
925
  return new MetricsImpl(this.name, () => this._nextGen.appName || InstrumentationImpl.defaultAppName);
@@ -900,7 +936,7 @@ class InstrumentationImpl {
900
936
  userSchema = simple;
901
937
  if (userSchemaOrText) {
902
938
  userData = {
903
- text: userSchemaOrText.substr(0, this._simpleTextMaxLength)
939
+ text: userSchemaOrText.substring(0, this._simpleTextMaxLength)
904
940
  };
905
941
  }
906
942
  else {
@@ -1123,17 +1159,46 @@ class InstrumentationImpl {
1123
1159
  _checkInputs(schema, data) {
1124
1160
  schemaUtil.checkSchema(schema);
1125
1161
  utility.requireArgument(data, 'data', 'object');
1162
+ let vEntries;
1126
1163
  let savedUserPayload;
1127
1164
  if (data.userPayload !== undefined && schemaUtil.isInternal(schema)) {
1128
1165
  savedUserPayload = data.userPayload;
1129
- logValidator.validate(savedUserPayload.schema, savedUserPayload.payload);
1166
+ vEntries = logValidator.validate(savedUserPayload.schema, savedUserPayload.payload, true);
1167
+ this._processValidationResults(schemaUtil.getSchemaId(savedUserPayload.schema), savedUserPayload.payload, vEntries);
1130
1168
  data.userPayload = undefined;
1131
1169
  }
1132
- logValidator.validate(schema, data);
1170
+ vEntries = logValidator.validate(schema, data, true);
1171
+ this._processValidationResults(schemaUtil.getSchemaId(schema), data, vEntries);
1133
1172
  if (savedUserPayload !== undefined) {
1134
1173
  data.userPayload = savedUserPayload;
1135
1174
  }
1136
1175
  }
1176
+ _processValidationResults(schemaId, data, ventries) {
1177
+ for (let i = 0; i < ventries.length; i += 1) {
1178
+ const ei = ventries[i];
1179
+ if (ei.errorCode == 6 ||
1180
+ ei.errorCode == 7) {
1181
+ const lfi = ei.fields.length - 1;
1182
+ const obj = this._traverseFields(data, ei.fields.slice(0, lfi));
1183
+ const field = ei.fields[lfi];
1184
+ if (ei.errorCode == 6) {
1185
+ obj[field] = obj[field].substring(0, maxStringLengthAppLimit);
1186
+ }
1187
+ else {
1188
+ obj[field].splice(maxItemCountAppLimit);
1189
+ }
1190
+ }
1191
+ else {
1192
+ throw new Error(ei.asMessage(schemaId));
1193
+ }
1194
+ }
1195
+ }
1196
+ _traverseFields(data, fields) {
1197
+ if (!fields.length) {
1198
+ return data;
1199
+ }
1200
+ return this._traverseFields(data[fields[0]], fields.slice(1));
1201
+ }
1137
1202
  getUpCounters() {
1138
1203
  return this._metrics.getUpCounters().filter((m) => m.getLastUpdatedOn());
1139
1204
  }
@@ -1147,6 +1212,34 @@ class InstrumentationImpl {
1147
1212
  utility.requireArgument(listener, 'listener', 'function');
1148
1213
  this._nextGen.registerForLogPrompt(listener);
1149
1214
  }
1215
+ activity(name, execute, options) {
1216
+ var _a, _b, _c, _d;
1217
+ const act = this.startActivity(name, options);
1218
+ try {
1219
+ return execute(act);
1220
+ }
1221
+ catch (err) {
1222
+ act.error(err, (_a = options === null || options === void 0 ? void 0 : options.errorPayload) === null || _a === void 0 ? void 0 : _a.schema, (_b = options === null || options === void 0 ? void 0 : options.errorPayload) === null || _b === void 0 ? void 0 : _b.payload);
1223
+ throw err;
1224
+ }
1225
+ finally {
1226
+ act.stop((_c = options === null || options === void 0 ? void 0 : options.stopPayload) === null || _c === void 0 ? void 0 : _c.schema, (_d = options === null || options === void 0 ? void 0 : options.stopPayload) === null || _d === void 0 ? void 0 : _d.payload);
1227
+ }
1228
+ }
1229
+ async activityAsync(name, execute, options) {
1230
+ var _a, _b, _c, _d;
1231
+ const act = this.startActivity(name, options);
1232
+ try {
1233
+ return await execute(act);
1234
+ }
1235
+ catch (err) {
1236
+ act.error(err, (_a = options === null || options === void 0 ? void 0 : options.errorPayload) === null || _a === void 0 ? void 0 : _a.schema, (_b = options === null || options === void 0 ? void 0 : options.errorPayload) === null || _b === void 0 ? void 0 : _b.payload);
1237
+ throw err;
1238
+ }
1239
+ finally {
1240
+ act.stop((_c = options === null || options === void 0 ? void 0 : options.stopPayload) === null || _c === void 0 ? void 0 : _c.schema, (_d = options === null || options === void 0 ? void 0 : options.stopPayload) === null || _d === void 0 ? void 0 : _d.payload);
1241
+ }
1242
+ }
1150
1243
  }
1151
1244
  InstrumentationImpl.defaultAppName = 'APP_NOT_REGISTERED';
1152
1245
 
@@ -1355,6 +1448,8 @@ class NextgenImpl {
1355
1448
  bucketValue: this._appInstr.bucketValue.bind(this._appInstr),
1356
1449
  networkInstrumentation: tracing.networkInstrumentation.bind(tracing),
1357
1450
  registerForLogPrompt: this._appInstr.registerForLogPrompt.bind(this._appInstr),
1451
+ activity: this._appInstr.activity.bind(this._appInstr),
1452
+ activityAsync: this._appInstr.activityAsync.bind(this._appInstr),
1358
1453
  startRootActivity: this._appInstr.startRootActivity.bind(this._appInstr),
1359
1454
  registerLogCollector: this.registerLogCollector.bind(this),
1360
1455
  registerMetricsCollector: this.registerMetricsCollector.bind(this),
@@ -1504,7 +1599,10 @@ class NextgenImpl {
1504
1599
  try {
1505
1600
  listener(reason);
1506
1601
  }
1507
- catch (_a) {
1602
+ catch (err) {
1603
+ if (!utility.isProduction) {
1604
+ throw err;
1605
+ }
1508
1606
  }
1509
1607
  }
1510
1608
  }