xref: /aosp_15_r20/external/libwebsockets/READMEs/README.lws_metrics.md (revision 1c60b9aca93fdbc9b5f19b2d2194c91294b22281)
1*1c60b9acSAndroid Build Coastguard Worker## `lws_metrics`
2*1c60b9acSAndroid Build Coastguard Worker
3*1c60b9acSAndroid Build Coastguard Worker### Introduction
4*1c60b9acSAndroid Build Coastguard Worker
5*1c60b9acSAndroid Build Coastguard Worker`lws_metrics` records and aggregates **events** at all lws layers.
6*1c60b9acSAndroid Build Coastguard Worker
7*1c60b9acSAndroid Build Coastguard WorkerThere are three distinct parts:
8*1c60b9acSAndroid Build Coastguard Worker
9*1c60b9acSAndroid Build Coastguard Worker - the architecture inside lws for collecting and aggregating / decimating the
10*1c60b9acSAndroid Build Coastguard Worker   events and maintaining statistics about them, these are lws_metric objects
11*1c60b9acSAndroid Build Coastguard Worker
12*1c60b9acSAndroid Build Coastguard Worker - an external handler for forwarding aggregated metrics.  An lws_system ops
13*1c60b9acSAndroid Build Coastguard Worker   interface to pass on the aggregated metrics to an external backend.  lws
14*1c60b9acSAndroid Build Coastguard Worker   presents its own public metrics objects and leaves it to the external
15*1c60b9acSAndroid Build Coastguard Worker   code to have a shim to marry the lws metrics up to whatever is needed in the
16*1c60b9acSAndroid Build Coastguard Worker   metrics backend
17*1c60b9acSAndroid Build Coastguard Worker
18*1c60b9acSAndroid Build Coastguard Worker - a policy for when to emit each type of aggregated information to the external
19*1c60b9acSAndroid Build Coastguard Worker   handler.  This can be specified in the generic Secure Streams policy, or
20*1c60b9acSAndroid Build Coastguard Worker   a linked-list of lws_metric_policy_t object passed it at context creation in
21*1c60b9acSAndroid Build Coastguard Worker   `info.metrics_policies`.
22*1c60b9acSAndroid Build Coastguard Worker
23*1c60b9acSAndroid Build Coastguard WorkerThe external backend interface code may itself make use of lws connectivity apis
24*1c60b9acSAndroid Build Coastguard Workerincluding Secure Streams itself, and lws metrics are available on that too.
25*1c60b9acSAndroid Build Coastguard Worker
26*1c60b9acSAndroid Build Coastguard Worker### `lws_metrics` policy-based reporting
27*1c60b9acSAndroid Build Coastguard Worker
28*1c60b9acSAndroid Build Coastguard WorkerNormally metrics implementations are fixed at build-time and cannot change
29*1c60b9acSAndroid Build Coastguard Workerwithout a coordinated reflash of devices along with a change of backend schema.
30*1c60b9acSAndroid Build Coastguard Worker
31*1c60b9acSAndroid Build Coastguard Worker`lws_metrics` separates out the objects and code necessary to collect and
32*1c60b9acSAndroid Build Coastguard Workeraggregate the data cheaply, and the reporting policy that controls if, or how
33*1c60b9acSAndroid Build Coastguard Workeroften, the results are reported to the external handler.
34*1c60b9acSAndroid Build Coastguard Worker
35*1c60b9acSAndroid Build Coastguard Worker![policy based metrics](/doc-assets/lws_metrics-policy.png)
36*1c60b9acSAndroid Build Coastguard Worker
37*1c60b9acSAndroid Build Coastguard WorkerMetrics are created with a namespace name and the policy applies itself to those
38*1c60b9acSAndroid Build Coastguard Workerby listing the names, with wildcards allowed, the policy applies to, eg if
39*1c60b9acSAndroid Build Coastguard Workerspecified in the Secure Streams JSON policy
40*1c60b9acSAndroid Build Coastguard Worker
41*1c60b9acSAndroid Build Coastguard Worker```
42*1c60b9acSAndroid Build Coastguard Worker	...
43*1c60b9acSAndroid Build Coastguard Worker	"metrics": [
44*1c60b9acSAndroid Build Coastguard Worker                {
45*1c60b9acSAndroid Build Coastguard Worker                        "name":         "tensecs",
46*1c60b9acSAndroid Build Coastguard Worker                        "us_schedule":  10000000,
47*1c60b9acSAndroid Build Coastguard Worker                        "report":	"cpu.*"
48*1c60b9acSAndroid Build Coastguard Worker                }, {
49*1c60b9acSAndroid Build Coastguard Worker                        "name":         "30secs",
50*1c60b9acSAndroid Build Coastguard Worker                        "us_schedule":  30000000,
51*1c60b9acSAndroid Build Coastguard Worker                        "report":       "n.cn.*, n.http.*, n.ss.*, vh.*"
52*1c60b9acSAndroid Build Coastguard Worker                }
53*1c60b9acSAndroid Build Coastguard Worker        ],
54*1c60b9acSAndroid Build Coastguard Worker        ...
55*1c60b9acSAndroid Build Coastguard Worker```
56*1c60b9acSAndroid Build Coastguard Worker
57*1c60b9acSAndroid Build Coastguard WorkerMetrics that do not have a reporting policy do not report, but continue to
58*1c60b9acSAndroid Build Coastguard Workeraggregate measurements in case they are bound to a policy dynamically later.
59*1c60b9acSAndroid Build Coastguard Worker
60*1c60b9acSAndroid Build Coastguard Worker### Freeform metrics naming
61*1c60b9acSAndroid Build Coastguard Worker
62*1c60b9acSAndroid Build Coastguard WorkerThere is no predefined metrics schema, metrics objects, including those created
63*1c60b9acSAndroid Build Coastguard Workerby applications, can independently choose their own name in a namespace like
64*1c60b9acSAndroid Build Coastguard Worker"cpu.srv" or "n.cn.dns", and can set a prefix for all metrics names created in a
65*1c60b9acSAndroid Build Coastguard Workercontext (by setting `info.metrics_prefix` at context creation time).
66*1c60b9acSAndroid Build Coastguard Worker
67*1c60b9acSAndroid Build Coastguard WorkerThis allows multiple processes in a single device to expose copies of the same
68*1c60b9acSAndroid Build Coastguard Workermetrics in an individually addressable way, eg, if the UI process specifies the
69*1c60b9acSAndroid Build Coastguard Workerprefix "ui", then its lws metrics like "cpu.srv" will actually be created as
70*1c60b9acSAndroid Build Coastguard Worker"ui.cpu.srv".
71*1c60b9acSAndroid Build Coastguard Worker
72*1c60b9acSAndroid Build Coastguard WorkerApplications can freely define their own `lws_metrics` measurements with their
73*1c60b9acSAndroid Build Coastguard Workerown names in the namespace too, without central registration, and refer to those
74*1c60b9acSAndroid Build Coastguard Workernames in the reporting policy same as any other metric names.
75*1c60b9acSAndroid Build Coastguard Worker
76*1c60b9acSAndroid Build Coastguard WorkerIf the metrics backend requires a fixed schema, the mapping between the
77*1c60b9acSAndroid Build Coastguard Worker`lws_metrics` names and the backend schema indexes will be done in the
78*1c60b9acSAndroid Build Coastguard Worker`lws_system` external reporting api implementation alone.  Metrics objects
79*1c60b9acSAndroid Build Coastguard Workercontain a `void * backend_opaque` that is ignored by lws and can be set and
80*1c60b9acSAndroid Build Coastguard Workerread by the external reporting handler implementation to facilitate that.
81*1c60b9acSAndroid Build Coastguard Worker
82*1c60b9acSAndroid Build Coastguard Worker### Histogram metrics tagging
83*1c60b9acSAndroid Build Coastguard Worker
84*1c60b9acSAndroid Build Coastguard WorkerHistogram metrics track differently-qualified results in the same metric, for
85*1c60b9acSAndroid Build Coastguard Workerexample the metric `n.cn.failures` maintains separate result counts for all
86*1c60b9acSAndroid Build Coastguard Workervariations and kinds of failure.
87*1c60b9acSAndroid Build Coastguard Worker
88*1c60b9acSAndroid Build Coastguard Worker```
89*1c60b9acSAndroid Build Coastguard Worker[2021/03/01 06:34:05:6570] U: my_metric_report: ssproxy.n.cn.failures{ss="badcert_selfsigned",hostname="invalidca.badcert.warmcat.com",peer="46.105.127.147",tls="invalidca"} 2
90*1c60b9acSAndroid Build Coastguard Worker[2021/03/01 06:34:05:6573] U: my_metric_report: ssproxy.n.cn.failures{hostname="invalidca.badcert.warmcat.com",peer="46.105.127.147",tls="invalidca"} 1
91*1c60b9acSAndroid Build Coastguard Worker[2021/03/01 06:34:05:6576] U: my_metric_report: ssproxy.n.cn.failures{ss="badcert_expired",hostname="warmcat.com",peer="46.105.127.147",tls="expired"} 2
92*1c60b9acSAndroid Build Coastguard Worker[2021/03/01 06:34:05:6578] U: my_metric_report: ssproxy.n.cn.failures{hostname="warmcat.com",peer="46.105.127.147",tls="expired"} 1
93*1c60b9acSAndroid Build Coastguard Worker[2021/03/01 06:34:05:6580] U: my_metric_report: ssproxy.n.cn.failures{ss="badcert_hostname",hostname="hostname.badcert.warmcat.com",peer="46.105.127.147",tls="hostname"} 2
94*1c60b9acSAndroid Build Coastguard Worker[2021/03/01 06:34:05:6583] U: my_metric_report: ssproxy.n.cn.failures{hostname="hostname.badcert.warmcat.com",peer="46.105.127.147",tls="hostname"} 1
95*1c60b9acSAndroid Build Coastguard Worker[2021/03/01 06:34:05:6585] U: my_metric_report: ssproxy.n.cn.failures{dns="nores -2"} 8
96*1c60b9acSAndroid Build Coastguard Worker```
97*1c60b9acSAndroid Build Coastguard Worker
98*1c60b9acSAndroid Build Coastguard WorkerThe user handler for metrics is expected to iterate these, in the provided
99*1c60b9acSAndroid Build Coastguard Workerexamples (eg, minimal-secure-streams-testsfail)
100*1c60b9acSAndroid Build Coastguard Worker
101*1c60b9acSAndroid Build Coastguard Worker```
102*1c60b9acSAndroid Build Coastguard Worker#if defined(LWS_WITH_SYS_METRICS)
103*1c60b9acSAndroid Build Coastguard Workerstatic int
104*1c60b9acSAndroid Build Coastguard Workermy_metric_report(lws_metric_pub_t *mp)
105*1c60b9acSAndroid Build Coastguard Worker{
106*1c60b9acSAndroid Build Coastguard Worker	lws_metric_bucket_t *sub = mp->u.hist.head;
107*1c60b9acSAndroid Build Coastguard Worker	char buf[192];
108*1c60b9acSAndroid Build Coastguard Worker
109*1c60b9acSAndroid Build Coastguard Worker	do {
110*1c60b9acSAndroid Build Coastguard Worker		if (lws_metrics_format(mp, &sub, buf, sizeof(buf)))
111*1c60b9acSAndroid Build Coastguard Worker			lwsl_user("%s: %s\n", __func__, buf);
112*1c60b9acSAndroid Build Coastguard Worker	} while ((mp->flags & LWSMTFL_REPORT_HIST) && sub);
113*1c60b9acSAndroid Build Coastguard Worker
114*1c60b9acSAndroid Build Coastguard Worker	/* 0 = leave metric to accumulate, 1 = reset the metric */
115*1c60b9acSAndroid Build Coastguard Worker
116*1c60b9acSAndroid Build Coastguard Worker	return 1;
117*1c60b9acSAndroid Build Coastguard Worker}
118*1c60b9acSAndroid Build Coastguard Worker
119*1c60b9acSAndroid Build Coastguard Workerstatic const lws_system_ops_t system_ops = {
120*1c60b9acSAndroid Build Coastguard Worker	.metric_report = my_metric_report,
121*1c60b9acSAndroid Build Coastguard Worker};
122*1c60b9acSAndroid Build Coastguard Worker
123*1c60b9acSAndroid Build Coastguard Worker#endif
124*1c60b9acSAndroid Build Coastguard Worker```
125*1c60b9acSAndroid Build Coastguard Worker
126*1c60b9acSAndroid Build Coastguard Worker### `lws_metrics` decimation
127*1c60b9acSAndroid Build Coastguard Worker
128*1c60b9acSAndroid Build Coastguard WorkerEvent information can easily be produced faster than it can be transmitted, or
129*1c60b9acSAndroid Build Coastguard Workeris useful to record if everything is working.  In the case that things are not
130*1c60b9acSAndroid Build Coastguard Workerworking, then eventually the number of events that are unable to be forwarded
131*1c60b9acSAndroid Build Coastguard Workerto the backend would overwhelm the local storage.
132*1c60b9acSAndroid Build Coastguard Worker
133*1c60b9acSAndroid Build Coastguard WorkerFor that reason, the metrics objects are designed to absorb and summarize a
134*1c60b9acSAndroid Build Coastguard Workerpotentially large number of events cheaply by aggregating them, so even extreme
135*1c60b9acSAndroid Build Coastguard Workersituations can be tracked meaningfully inbetween dumps to the backend.
136*1c60b9acSAndroid Build Coastguard Worker
137*1c60b9acSAndroid Build Coastguard WorkerThere are two approaches:
138*1c60b9acSAndroid Build Coastguard Worker
139*1c60b9acSAndroid Build Coastguard Worker - "aggregation": decimate keeping a uint64 mean + sum, along with a max and min
140*1c60b9acSAndroid Build Coastguard Worker
141*1c60b9acSAndroid Build Coastguard Worker - "histogram": keep a linked-list of different named buckets, with a 64-bit
142*1c60b9acSAndroid Build Coastguard Worker   counter for the number of times an event in each bucket was observed
143*1c60b9acSAndroid Build Coastguard Worker
144*1c60b9acSAndroid Build Coastguard WorkerA single metric aggregation object has separate "go / no-go" counters, since
145*1c60b9acSAndroid Build Coastguard Workermost operations can fail, and failing operations act differently.
146*1c60b9acSAndroid Build Coastguard Worker
147*1c60b9acSAndroid Build Coastguard Worker`lws_metrics` 'aggregation' supports decimation by
148*1c60b9acSAndroid Build Coastguard Worker
149*1c60b9acSAndroid Build Coastguard Worker - a mean of a 64-bit event metric, separate for go and no-go events
150*1c60b9acSAndroid Build Coastguard Worker - counters of go and no-go events
151*1c60b9acSAndroid Build Coastguard Worker - a min and max of the metric
152*1c60b9acSAndroid Build Coastguard Worker - keeping track of when the sample period started
153*1c60b9acSAndroid Build Coastguard Worker
154*1c60b9acSAndroid Build Coastguard Worker![metrics decimation](/doc-assets/lws_metrics-decimation.png)
155*1c60b9acSAndroid Build Coastguard Worker
156*1c60b9acSAndroid Build Coastguard WorkerIn addition, the policy defines a percentage variance from the mean that
157*1c60b9acSAndroid Build Coastguard Workeroptionally qualifies events to be reported individually.
158*1c60b9acSAndroid Build Coastguard Worker
159*1c60b9acSAndroid Build Coastguard WorkerThe `lws_metrics` 'histogram' allows monitoring of different outcomes to
160*1c60b9acSAndroid Build Coastguard Workerproduce counts of each outcome in the "bucket".
161*1c60b9acSAndroid Build Coastguard Worker
162*1c60b9acSAndroid Build Coastguard Worker### `lws_metrics` flags
163*1c60b9acSAndroid Build Coastguard Worker
164*1c60b9acSAndroid Build Coastguard WorkerWhen the metrics object is created, flags are used to control how it will be
165*1c60b9acSAndroid Build Coastguard Workerused and consumed.
166*1c60b9acSAndroid Build Coastguard Worker
167*1c60b9acSAndroid Build Coastguard WorkerFor example to create a histogram metrics object rather than the default
168*1c60b9acSAndroid Build Coastguard Workeraggregation type, you would give the flag `LWSMTFL_REPORT_HIST` at creation
169*1c60b9acSAndroid Build Coastguard Workertime.
170*1c60b9acSAndroid Build Coastguard Worker
171*1c60b9acSAndroid Build Coastguard Worker|Flag|Meaning|
172*1c60b9acSAndroid Build Coastguard Worker|---|---|
173*1c60b9acSAndroid Build Coastguard Worker|`LWSMTFL_REPORT_OUTLIERS`|track outliers and report them internally|
174*1c60b9acSAndroid Build Coastguard Worker|`LWSMTFL_REPORT_OUTLIERS_OOB`|report each outlier externally as they happen|
175*1c60b9acSAndroid Build Coastguard Worker|`LWSMTFL_REPORT_INACTIVITY_AT_PERIODIC`|explicitly externally report no activity at periodic cb, by default no events in the period is just not reported|
176*1c60b9acSAndroid Build Coastguard Worker|`LWSMTFL_REPORT_MEAN`|the mean is interesting for this metric|
177*1c60b9acSAndroid Build Coastguard Worker|`LWSMTFL_REPORT_ONLY_GO`|no-go pieces invalid and should be ignored, used for simple counters|
178*1c60b9acSAndroid Build Coastguard Worker|`LWSMTFL_REPORT_DUTY_WALLCLOCK_US`|the aggregated sum or mean can be compared to wallclock time|
179*1c60b9acSAndroid Build Coastguard Worker|`LWSMTFL_REPORT_HIST`|object is a histogram (else aggregator)|
180*1c60b9acSAndroid Build Coastguard Worker
181*1c60b9acSAndroid Build Coastguard Worker### Built-in lws-layer metrics
182*1c60b9acSAndroid Build Coastguard Worker
183*1c60b9acSAndroid Build Coastguard Workerlws creates and maintains various well-known metrics when you enable build
184*1c60b9acSAndroid Build Coastguard Workerwith cmake `-DLWS_WITH_SYS_METRICS=1`:
185*1c60b9acSAndroid Build Coastguard Worker
186*1c60b9acSAndroid Build Coastguard Worker#### Aggregation metrics
187*1c60b9acSAndroid Build Coastguard Worker|metric name|scope|type|meaning|
188*1c60b9acSAndroid Build Coastguard Worker---|---|---|---|
189*1c60b9acSAndroid Build Coastguard Worker`cpu.svc`|context|monotonic over time|time spent servicing, outside of event loop wait|
190*1c60b9acSAndroid Build Coastguard Worker`n.cn.dns`|context|go/no-go mean|duration of blocking libc DNS lookup|
191*1c60b9acSAndroid Build Coastguard Worker`n.cn.adns`|context|go/no-go mean|duration of SYS_ASYNC_DNS lws DNS lookup|
192*1c60b9acSAndroid Build Coastguard Worker`n.cn.tcp`|context|go/no-go mean|duration of tcp connection until accept|
193*1c60b9acSAndroid Build Coastguard Worker`n.cn.tls`|context|go/no-go mean|duration of tls connection until accept|
194*1c60b9acSAndroid Build Coastguard Worker`n.http.txn`|context|go (2xx)/no-go mean|duration of lws http transaction|
195*1c60b9acSAndroid Build Coastguard Worker`n.ss.conn`|context|go/no-go mean|duration of Secure Stream transaction|
196*1c60b9acSAndroid Build Coastguard Worker`n.ss.cliprox.conn`|context|go/no-go mean|time taken for client -> proxy connection|
197*1c60b9acSAndroid Build Coastguard Worker`vh.[vh-name].rx`|vhost|go/no-go sum|received data on the vhost|
198*1c60b9acSAndroid Build Coastguard Worker`vh.[vh-name].tx`|vhost|go/no-go sum|transmitted data on the vhost|
199*1c60b9acSAndroid Build Coastguard Worker
200*1c60b9acSAndroid Build Coastguard Worker#### Histogram metrics
201*1c60b9acSAndroid Build Coastguard Worker|metric name|scope|type|meaning|
202*1c60b9acSAndroid Build Coastguard Worker|---|---|---|---|
203*1c60b9acSAndroid Build Coastguard Worker`n.cn.failures`|context|histogram|Histogram of connection attempt failure reasons|
204*1c60b9acSAndroid Build Coastguard Worker
205*1c60b9acSAndroid Build Coastguard Worker#### Connection failure histogram buckets
206*1c60b9acSAndroid Build Coastguard Worker|Bucket name|Meaning|
207*1c60b9acSAndroid Build Coastguard Worker|---|---|
208*1c60b9acSAndroid Build Coastguard Worker`tls/invalidca`|Peer certificate CA signature missing or not trusted|
209*1c60b9acSAndroid Build Coastguard Worker`tls/hostname`|Peer certificate CN or SAN doesn't match the endpoint we asked for|
210*1c60b9acSAndroid Build Coastguard Worker`tls/notyetvalid`|Peer certificate start date is in the future (time wrong?)|
211*1c60b9acSAndroid Build Coastguard Worker`tls/expired`|Peer certificate is expiry date is in the past|
212*1c60b9acSAndroid Build Coastguard Worker`dns/badsrv`|No DNS result because couldn't talk to the server|
213*1c60b9acSAndroid Build Coastguard Worker`dns/nxdomain`|No DNS result because server says no result|
214*1c60b9acSAndroid Build Coastguard Worker
215*1c60b9acSAndroid Build Coastguard WorkerThe `lws-minimal-secure-streams` example is able to report the aggregated
216*1c60b9acSAndroid Build Coastguard Workermetrics at the end of execution, eg
217*1c60b9acSAndroid Build Coastguard Worker
218*1c60b9acSAndroid Build Coastguard Worker```
219*1c60b9acSAndroid Build Coastguard Worker[2021/01/13 11:47:19:9145] U: my_metric_report: cpu.svc: 137.045ms / 884.563ms (15%)
220*1c60b9acSAndroid Build Coastguard Worker[2021/01/13 11:47:19:9145] U: my_metric_report: n.cn.dns: Go: 4, mean: 3.792ms, min: 2.470ms, max: 5.426ms
221*1c60b9acSAndroid Build Coastguard Worker[2021/01/13 11:47:19:9145] U: my_metric_report: n.cn.tcp: Go: 4, mean: 40.633ms, min: 17.107ms, max: 94.560ms
222*1c60b9acSAndroid Build Coastguard Worker[2021/01/13 11:47:19:9145] U: my_metric_report: n.cn.tls: Go: 3, mean: 91.232ms, min: 30.322ms, max: 204.635ms
223*1c60b9acSAndroid Build Coastguard Worker[2021/01/13 11:47:19:9145] U: my_metric_report: n.http.txn: Go: 4, mean: 63.089ms, min: 20.184ms, max: 125.474ms
224*1c60b9acSAndroid Build Coastguard Worker[2021/01/13 11:47:19:9145] U: my_metric_report: n.ss.conn: Go: 4, mean: 161.740ms, min: 42.937ms, max: 429.510ms
225*1c60b9acSAndroid Build Coastguard Worker[2021/01/13 11:47:19:9145] U: my_metric_report: vh._ss_default.rx: Go: (1) 102, NoGo: (1) 0
226*1c60b9acSAndroid Build Coastguard Worker[2021/01/13 11:47:19:9145] U: my_metric_report: vh.le_via_dst.rx: Go: (22) 28.165Ki
227*1c60b9acSAndroid Build Coastguard Worker[2021/01/13 11:47:19:9145] U: my_metric_report: vh.le_via_dst.tx: Go: (1) 267
228*1c60b9acSAndroid Build Coastguard Worker[2021/01/13 11:47:19:9145] U: my_metric_report: vh.api_amazon_com.rx: Go: (1) 1.611Ki, NoGo: (1) 0
229*1c60b9acSAndroid Build Coastguard Worker[2021/01/13 11:47:19:9145] U: my_metric_report: vh.api_amazon_com.tx: Go: (3) 1.505Ki
230*1c60b9acSAndroid Build Coastguard Worker```
231*1c60b9acSAndroid Build Coastguard Worker
232*1c60b9acSAndroid Build Coastguard Workerlws-minimal-secure-stream-testsfail which tests various kinds of connection failure
233*1c60b9acSAndroid Build Coastguard Workerreports histogram results like this
234*1c60b9acSAndroid Build Coastguard Worker
235*1c60b9acSAndroid Build Coastguard Worker```
236*1c60b9acSAndroid Build Coastguard Worker[2021/01/15 13:10:16:0933] U: my_metric_report: n.cn.failures: tot: 36, [ tls/invalidca: 5, tls/expired: 5, tls/hostname: 5, dns/nxdomain: 21 ]
237*1c60b9acSAndroid Build Coastguard Worker```
238*1c60b9acSAndroid Build Coastguard Worker
239*1c60b9acSAndroid Build Coastguard Worker## Support for openmetrics
240*1c60b9acSAndroid Build Coastguard Worker
241*1c60b9acSAndroid Build Coastguard WorkerOpenmetrics https://tools.ietf.org/html/draft-richih-opsawg-openmetrics-00
242*1c60b9acSAndroid Build Coastguard Workerdefines a textual metrics export format comaptible with Prometheus.  Lws
243*1c60b9acSAndroid Build Coastguard Workerprovides a protocol plugin in `./plugins/protocol_lws_openmetrics_export`
244*1c60b9acSAndroid Build Coastguard Workerthat enables direct export for prometheus scraping, and also protocols to
245*1c60b9acSAndroid Build Coastguard Workerproxy openmetrics export for unreachable servers.
246