@lwrjs/o11y 0.6.0-alpha.9 → 0.6.2

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.
@@ -1 +1 @@
1
- import{getInstrumentation as t}from"o11y/client";import{registerDecorators as r}from"lwc";class e{constructor(t){this.marks={},this.instrumentation=t}track(){this.trackExistingMarks(),this.setupObserver()}trackExistingMarks(){const t=performance.getEntriesByType("mark").filter((t=>t.name.startsWith("lwr.loader.module.define")));t.length>0&&this.instrumentation.incrementCounter("lwr.loader.module.define.count",t.length)}setupObserver(){let t=0;new PerformanceObserver((r=>{const e=[];r.getEntries().forEach((r=>{const{name:n,entryType:s}=r;"mark"===s&&n.startsWith("lwr.")&&e.push(r),"lwr.bootstrap.end"===n&&(this.marks[n]=r),"lwr.bootstrap.error"===n&&(t+=1)})),void 0!==this.marks["lwr.bootstrap.end"]&&(this.instrumentation.trackValue("lwr.bootstrap.duration",this.marks["lwr.bootstrap.end"].startTime),this.instrumentation.trackValue("lwr.bootstrap.availability",1/(1+t)*100),delete this.marks["lwr.bootstrap.end"]);const n=e.reduce(((t,r)=>r.name.startsWith("lwr.loader.module.define")?t+1:t),0);n>0&&this.instrumentation.incrementCounter("lwr.loader.module.define.count",n);const s=e.reduce(((t,r)=>r.name.startsWith("lwr.loader.module.fetch")?t+1:t),0);s>0&&this.instrumentation.incrementCounter("lwr.loader.module.fetch.count",s);const o=e.reduce(((t,r)=>r.name.startsWith("lwr.loader.mappings.fetch")?t+1:t),0);o>0&&this.instrumentation.incrementCounter("lwr.loader.mappings.fetch.count",o),e.forEach((t=>performance.clearMarks(t.name)))})).observe({entryTypes:["mark"]})}}r(e,{fields:["marks"]});const n=void 0!==globalThis.performance&&"function"==typeof globalThis.performance.mark,s={track:()=>{}};function o(r){const o=t("lwrjs.instrumentation");(n?new e(o):s).track()}export default o;
1
+ import{getInstrumentation as t}from"o11y/client";import{registerDecorators as r}from"lwc";import{MODULE_FETCH as e,MAPPINGS_FETCH as s,MODULE_DEFINE as n,MODULE_DEFINE_COUNT as i,BOOTSTRAP_END as a,MODULE_FETCH_DURATION as o,MAPPINGS_FETCH_DURATION as m,BOOTSTRAP_DURATION as c,BOOTSTRAP_AVAILABILITY as h,MODULE_FETCH_COUNT as u,MODULE_AVAILABILITY as l,MAPPINGS_FETCH_COUNT as k,MAPPINGS_AVAILABILITY as f,BOOTSTRAP_ERROR as p,MODULE_ERROR as d,MAPPINGS_ERROR as W}from"lwr/metrics";class b{constructor(t){this.marks={},this.instrumentation=t}track(){this.trackExistingMarks(),this.setupObserver()}isClearable(t){return!t.startsWith(e)&&!t.startsWith(s)}trackExistingMarks(){const t=performance.getEntriesByType("mark").filter((t=>t.name.startsWith(n)));t.length>0&&this.instrumentation.incrementCounter(i,t.length)}setupObserver(){let t=0,r=0,b=0;new PerformanceObserver((g=>{const y=[];g.getEntries().forEach((e=>{const{name:s,entryType:n,duration:i}=e;"mark"===n&&s.startsWith("lwr.")&&y.push(e),s===a&&(this.marks[s]=e),s===p&&(t+=1),s===d&&(r+=1),s===W&&(b+=1),(s.startsWith(o)||s.startsWith(m))&&this.instrumentation.trackValue(s,i)})),void 0!==this.marks[a]&&(this.instrumentation.trackValue(c,this.marks[a].startTime),this.instrumentation.trackValue(h,1/(1+t)*100),delete this.marks[a]);const v=y.reduce(((t,r)=>r.name.startsWith(n)?t+1:t),0);v>0&&this.instrumentation.incrementCounter(i,v);const w=y.reduce(((t,r)=>r.name.startsWith(e)?t+1:t),0);w>0&&(this.instrumentation.incrementCounter(u,w),this.instrumentation.trackValue(l,w/(w+r)*100));const C=y.reduce(((t,r)=>r.name.startsWith(s)?t+1:t),0);C>0&&(this.instrumentation.incrementCounter(k,C),this.instrumentation.trackValue(f,C/(C+b)*100)),y.forEach((t=>this.isClearable(t.name)&&performance.clearMarks(t.name)))})).observe({entryTypes:["mark","measure"]})}}r(b,{fields:["marks"]});const g=void 0!==globalThis.performance&&"function"==typeof globalThis.performance.mark,y={track:()=>{}};function v(r){const e=t("lwrjs");(g?new b(e):y).track()}export default v;
@@ -10,12 +10,13 @@ const noop = () => {// noop
10
10
  const noopSink = {
11
11
  track: noop
12
12
  };
13
+ const NAMESPACE = 'lwrjs';
13
14
  /**
14
15
  * Sets up o11y instrumentation instance.
15
16
  */
16
17
 
17
- export default function hookO11yClient(loaderServices) {
18
- const instrumentation = getInstrumentation('lwrjs.instrumentation');
18
+ export default function hookO11yClient(serviceApi) {
19
+ const instrumentation = getInstrumentation(NAMESPACE);
19
20
  const sink = isPerfSupported ? new PerformanceApiSink(instrumentation) : noopSink;
20
21
  sink.track();
21
22
  }
@@ -1,14 +1,4 @@
1
- // TODO: import constants from shared util module
2
- const BOOTSTRAP_END_MARK = 'lwr.bootstrap.end';
3
- const BOOTSTRAP_ERROR_MARK = 'lwr.bootstrap.error';
4
- const BOOTSTRAP_DURATION_OP = 'lwr.bootstrap.duration';
5
- const BOOTSTRAP_AVAILABILITY_OP = 'lwr.bootstrap.availability';
6
- const LOADER_MODULE_DEFINE = 'lwr.loader.module.define';
7
- const LOADER_MODULE_DEFINE_COUNT = 'lwr.loader.module.define.count';
8
- const LOADER_MODULE_FETCH = 'lwr.loader.module.fetch';
9
- const LOADER_MODULE_FETCH_COUNT = 'lwr.loader.module.fetch.count';
10
- const LOADER_MAPPING_FETCH = 'lwr.loader.mappings.fetch';
11
- const LOADER_MAPPING_FETCH_COUNT = 'lwr.loader.mappings.fetch.count';
1
+ import { BOOTSTRAP_AVAILABILITY, BOOTSTRAP_DURATION, BOOTSTRAP_END, BOOTSTRAP_ERROR, MAPPINGS_AVAILABILITY, MAPPINGS_ERROR, MAPPINGS_FETCH, MAPPINGS_FETCH_COUNT, MAPPINGS_FETCH_DURATION, MODULE_AVAILABILITY, MODULE_DEFINE, MODULE_DEFINE_COUNT, MODULE_ERROR, MODULE_FETCH, MODULE_FETCH_COUNT, MODULE_FETCH_DURATION } from 'lwr/metrics';
12
2
  export class PerformanceApiSink {
13
3
  marks = {};
14
4
 
@@ -19,15 +9,21 @@ export class PerformanceApiSink {
19
9
  track() {
20
10
  this.trackExistingMarks();
21
11
  this.setupObserver();
12
+ } // Return true if the mark is clearable
13
+ // logOperationEnd clears the marks and measures passed to it, so these are NOT clearable
14
+ // As of now, only "lwr.loader.*.fetch" metrics have durations (i.e. are not clearable)
15
+
16
+
17
+ isClearable(name) {
18
+ return !name.startsWith(MODULE_FETCH) && !name.startsWith(MAPPINGS_FETCH);
22
19
  } // Retrieve existing metrics to this point
23
20
 
24
21
 
25
22
  trackExistingMarks() {
26
23
  /**
27
- * Loader marks prior to service bootstrap:
28
- * - lwr.loader.module.define
24
+ * Loader define marks prior to service bootstrap
29
25
  */
30
- const marks = performance.getEntriesByType('mark').filter(e => e.name.startsWith(LOADER_MODULE_DEFINE)); // initialize the module define count
26
+ const marks = performance.getEntriesByType('mark').filter(e => e.name.startsWith(MODULE_DEFINE)); // initialize the module define count
31
27
  // at this point in time, the count will include modules NOT fetched by the loader:
32
28
  // - required modules
33
29
  // - preload modules
@@ -35,7 +31,7 @@ export class PerformanceApiSink {
35
31
  // - the loader module itself
36
32
 
37
33
  if (marks.length > 0) {
38
- this.instrumentation.incrementCounter(LOADER_MODULE_DEFINE_COUNT, marks.length);
34
+ this.instrumentation.incrementCounter(MODULE_DEFINE_COUNT, marks.length);
39
35
  }
40
36
  } // Add observer to log future metrics
41
37
  // observe lwr client runtime performance metrics
@@ -43,74 +39,88 @@ export class PerformanceApiSink {
43
39
 
44
40
  setupObserver() {
45
41
  let bootstrapErrorCount = 0;
42
+ let loaderModuleErrorCount = 0;
43
+ let loaderMappingsErrorcount = 0;
46
44
  const observer = new PerformanceObserver(list => {
47
45
  // grab the lwr performance marks
48
46
  const marks = [];
49
47
  /**
50
- * Bootstrap marks after to service bootstrap:
51
- * - lwr.bootstrap.end
52
- * - lwr.bootstrap.error
53
- * Loader marks
54
- * - lwr.loader.*
48
+ * Bootstrap and Loader marks
55
49
  */
56
50
 
57
51
  list.getEntries().forEach(entry => {
58
52
  const {
59
53
  name,
60
- entryType
54
+ entryType,
55
+ duration
61
56
  } = entry;
62
57
 
63
58
  if (entryType === 'mark' && name.startsWith('lwr.')) {
64
59
  marks.push(entry);
65
60
  }
66
61
 
67
- if (name === BOOTSTRAP_END_MARK) {
62
+ if (name === BOOTSTRAP_END) {
68
63
  this.marks[name] = entry;
69
64
  }
70
65
 
71
- if (name === BOOTSTRAP_ERROR_MARK) {
66
+ if (name === BOOTSTRAP_ERROR) {
72
67
  bootstrapErrorCount += 1;
73
68
  }
69
+
70
+ if (name === MODULE_ERROR) {
71
+ loaderModuleErrorCount += 1;
72
+ }
73
+
74
+ if (name === MAPPINGS_ERROR) {
75
+ loaderMappingsErrorcount += 1;
76
+ }
77
+
78
+ if (name.startsWith(MODULE_FETCH_DURATION) || name.startsWith(MAPPINGS_FETCH_DURATION)) {
79
+ this.instrumentation.trackValue(name, duration);
80
+ }
74
81
  });
75
82
 
76
- if (this.marks[BOOTSTRAP_END_MARK] !== undefined) {
77
- this.instrumentation.trackValue(BOOTSTRAP_DURATION_OP, this.marks[BOOTSTRAP_END_MARK].startTime);
78
- this.instrumentation.trackValue(BOOTSTRAP_AVAILABILITY_OP, 1 / (1 + bootstrapErrorCount) * 100); // reset to prevent multiple reports
83
+ if (this.marks[BOOTSTRAP_END] !== undefined) {
84
+ this.instrumentation.trackValue(BOOTSTRAP_DURATION, this.marks[BOOTSTRAP_END].startTime);
85
+ this.instrumentation.trackValue(BOOTSTRAP_AVAILABILITY, 1 / (1 + bootstrapErrorCount) * 100); // reset to prevent multiple reports
79
86
 
80
- delete this.marks[BOOTSTRAP_END_MARK];
87
+ delete this.marks[BOOTSTRAP_END];
81
88
  } // count how many modules were defined and report the count
82
89
 
83
90
 
84
91
  const moduleDefineCount = marks.reduce((count, mark) => {
85
- return mark.name.startsWith(LOADER_MODULE_DEFINE) ? count + 1 : count;
92
+ return mark.name.startsWith(MODULE_DEFINE) ? count + 1 : count;
86
93
  }, 0);
87
94
 
88
95
  if (moduleDefineCount > 0) {
89
- this.instrumentation.incrementCounter(LOADER_MODULE_DEFINE_COUNT, moduleDefineCount);
96
+ this.instrumentation.incrementCounter(MODULE_DEFINE_COUNT, moduleDefineCount);
90
97
  } // count how many modules were loaded and report the count
91
98
 
92
99
 
93
100
  const moduleLoadCount = marks.reduce((count, mark) => {
94
- return mark.name.startsWith(LOADER_MODULE_FETCH) ? count + 1 : count;
101
+ return mark.name.startsWith(MODULE_FETCH) ? count + 1 : count;
95
102
  }, 0);
96
103
 
97
104
  if (moduleLoadCount > 0) {
98
- this.instrumentation.incrementCounter(LOADER_MODULE_FETCH_COUNT, moduleLoadCount);
105
+ this.instrumentation.incrementCounter(MODULE_FETCH_COUNT, moduleLoadCount);
106
+ this.instrumentation.trackValue(MODULE_AVAILABILITY, moduleLoadCount / (moduleLoadCount + loaderModuleErrorCount) * 100);
99
107
  } // count how many mapping resources were loaded and report the count
100
108
 
101
109
 
102
110
  const mappingLoadCount = marks.reduce((count, mark) => {
103
- return mark.name.startsWith(LOADER_MAPPING_FETCH) ? count + 1 : count;
111
+ return mark.name.startsWith(MAPPINGS_FETCH) ? count + 1 : count;
104
112
  }, 0);
105
113
 
106
114
  if (mappingLoadCount > 0) {
107
- this.instrumentation.incrementCounter(LOADER_MAPPING_FETCH_COUNT, mappingLoadCount);
108
- }
115
+ this.instrumentation.incrementCounter(MAPPINGS_FETCH_COUNT, mappingLoadCount);
116
+ this.instrumentation.trackValue(MAPPINGS_AVAILABILITY, mappingLoadCount / (mappingLoadCount + loaderMappingsErrorcount) * 100);
117
+ } // remove clearable marks
118
+
109
119
 
110
- marks.forEach(mark => performance.clearMarks(mark.name));
120
+ marks.forEach(mark => this.isClearable(mark.name) && performance.clearMarks(mark.name));
111
121
  });
112
122
  observer.observe({
113
- entryTypes: ['mark']
123
+ entryTypes: ['mark', 'measure']
114
124
  });
115
125
  }
116
126
 
package/package.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
7
- "version": "0.6.0-alpha.9",
7
+ "version": "0.6.2",
8
8
  "homepage": "https://developer.salesforce.com/docs/platform/lwr/overview",
9
9
  "repository": {
10
10
  "type": "git",
@@ -24,8 +24,8 @@
24
24
  "build:bundle": "rollup --config scripts/rollup.moduleBundle.config.cjs"
25
25
  },
26
26
  "dependencies": {
27
- "@lwrjs/shared-utils": "0.6.0-alpha.9",
28
- "o11y": "238.1.2"
27
+ "@lwrjs/shared-utils": "0.6.2",
28
+ "o11y": "238.1.4"
29
29
  },
30
30
  "devDependencies": {
31
31
  "rollup-plugin-terser": "^7.0.2"
@@ -46,5 +46,5 @@
46
46
  "engines": {
47
47
  "node": ">=14.15.4 <17"
48
48
  },
49
- "gitHead": "9cb371a5d01ef345660138a48fe0b3f0119d0799"
49
+ "gitHead": "ef85bdc48adde58b7c648561d67acbb408bbe189"
50
50
  }