@sentio/runtime 0.0.0-rc.a

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.
@@ -0,0 +1,33 @@
1
+ import { ExecutionConfig } from './gen/processor/protos/processor.js'
2
+
3
+ export interface GlobalConfig {
4
+ execution: Partial<ExecutionConfig>
5
+ }
6
+
7
+ // Experimental global config, only apply to eth for now
8
+ export const GLOBAL_CONFIG: GlobalConfig = {
9
+ execution: {
10
+ sequential: false,
11
+ forceExactBlockTime: false
12
+ }
13
+ }
14
+
15
+ export function freezeGlobalConfig() {
16
+ deepFreeze(GLOBAL_CONFIG.execution)
17
+ }
18
+
19
+ export function deepFreeze(object: any) {
20
+ // Retrieve the property names defined on object
21
+ const propNames = Reflect.ownKeys(object)
22
+
23
+ // Freeze properties before freezing self
24
+ for (const name of propNames) {
25
+ const value = object[name]
26
+
27
+ if ((value && typeof value === 'object') || typeof value === 'function') {
28
+ deepFreeze(value)
29
+ }
30
+ }
31
+
32
+ return Object.freeze(object)
33
+ }
package/src/index.ts ADDED
@@ -0,0 +1,10 @@
1
+ export * from './plugin.js'
2
+ export * from './state.js'
3
+ export * from './utils.js'
4
+ export * from './endpoints.js'
5
+ export * from './chain-config.js'
6
+ export * from './service.js'
7
+ export { GLOBAL_CONFIG, type GlobalConfig } from './global-config.js'
8
+ export * from './db-context.js'
9
+ export * from './provider.js'
10
+ export * from './metrics.js'
package/src/logger.ts ADDED
@@ -0,0 +1,59 @@
1
+ import { createLogger, format, transports } from 'winston'
2
+
3
+ function stringify(obj: any): string {
4
+ const cache = new WeakSet()
5
+ return JSON.stringify(obj, function (key, value) {
6
+ if (typeof value === 'object' && value !== null) {
7
+ if (cache.has(value)) {
8
+ return '[Circular]'
9
+ }
10
+ cache.add(value)
11
+ }
12
+ return value
13
+ })
14
+ }
15
+
16
+ export function setupLogger(json: boolean, enableDebug: boolean) {
17
+ const utilFormatter = {
18
+ transform: (info: any) => {
19
+ const stringRes = []
20
+
21
+ if (typeof info.message === 'object') {
22
+ stringRes.push(stringify(info.message))
23
+ } else {
24
+ stringRes.push(info.message)
25
+ }
26
+
27
+ const args = info[Symbol.for('splat')]
28
+ if (args) {
29
+ for (const idx in args) {
30
+ const arg = args[idx]
31
+ if (typeof arg === 'object') {
32
+ stringRes.push(stringify(arg))
33
+ } else {
34
+ stringRes.push(arg)
35
+ }
36
+ }
37
+ }
38
+
39
+ info.message = stringRes.join(' ')
40
+ return info
41
+ }
42
+ }
43
+ const logger = createLogger({
44
+ format: format.combine(
45
+ format.timestamp({ format: 'YYYY-MM-DDTHH:mm:ss.SSSZ' }),
46
+ utilFormatter,
47
+ format.errors({ stack: true }),
48
+ json ? format.json() : format.simple()
49
+ ),
50
+ level: enableDebug ? 'debug' : 'info',
51
+ transports: [new transports.Console()]
52
+ })
53
+
54
+ console.log = (...args) => logger.info.call(logger, ...args)
55
+ console.info = (...args) => logger.info.call(logger, ...args)
56
+ console.warn = (...args) => logger.warn.call(logger, ...args)
57
+ console.error = (...args) => logger.error.call(logger, ...args)
58
+ console.debug = (...args) => logger.debug.call(logger, ...args)
59
+ }
package/src/metrics.ts ADDED
@@ -0,0 +1,202 @@
1
+ import { AsyncLocalStorage } from 'node:async_hooks'
2
+ import { Attributes, Counter, metrics, Gauge, Histogram } from '@opentelemetry/api'
3
+
4
+ const getMeter = () => metrics.getMeter('processor')
5
+
6
+ class C {
7
+ private _counter: Counter<Attributes>
8
+ private value: number = 0
9
+
10
+ constructor(private name: string) {}
11
+
12
+ get counter(): Counter<Attributes> {
13
+ if (!this._counter) {
14
+ this._counter = getMeter().createCounter(this.name)
15
+ }
16
+ return this._counter
17
+ }
18
+
19
+ add(value: number, attributes?: Attributes) {
20
+ this.counter.add(value, attributes)
21
+ this.value += value
22
+ }
23
+
24
+ get() {
25
+ return this.value
26
+ }
27
+ }
28
+
29
+ class G {
30
+ private _gauge: Gauge<Attributes>
31
+ private value: number = 0
32
+
33
+ constructor(private name: string) {}
34
+
35
+ get gauge(): Gauge<Attributes> {
36
+ if (!this._gauge) {
37
+ this._gauge = getMeter().createGauge(this.name)
38
+ }
39
+ return this._gauge
40
+ }
41
+
42
+ record(value: number, attributes?: Attributes) {
43
+ this.gauge.record(value, attributes)
44
+ this.value = value
45
+ }
46
+
47
+ get() {
48
+ return this.value
49
+ }
50
+ }
51
+
52
+ class H {
53
+ private _histogram: Histogram<Attributes>
54
+ private value: number = 0
55
+
56
+ constructor(private name: string) {}
57
+
58
+ get histogram(): Histogram<Attributes> {
59
+ if (!this._histogram) {
60
+ this._histogram = getMeter().createHistogram(this.name)
61
+ }
62
+ return this._histogram
63
+ }
64
+
65
+ record(value: number, attributes?: Attributes) {
66
+ this.histogram.record(value, attributes)
67
+ this.value = value
68
+ }
69
+
70
+ get() {
71
+ return this.value
72
+ }
73
+ }
74
+
75
+ export const dbMetrics = {
76
+ send_counts: {
77
+ get: new C('store_get_send'),
78
+ upsert: new C('store_upsert_send'),
79
+ list: new C('store_list_send'),
80
+ delete: new C('store_delete_send')
81
+ },
82
+ recv_counts: {
83
+ get: new C('store_get_recv'),
84
+ upsert: new C('store_upsert_recv'),
85
+ list: new C('store_list_recv'),
86
+ delete: new C('store_delete_recv')
87
+ },
88
+ request_times: {
89
+ get: new C('store_get_time'),
90
+ upsert: new C('store_upsert_time'),
91
+ list: new C('store_list_time'),
92
+ delete: new C('store_delete_time')
93
+ },
94
+ request_errors: {
95
+ get: new C('store_get_error'),
96
+ upsert: new C('store_upsert_error'),
97
+ list: new C('store_list_error'),
98
+ delete: new C('store_delete_error')
99
+ },
100
+ batched_total_count: new C('batched_total_count'),
101
+ batched_request_count: new C('batched_request_count'),
102
+ unsolved_requests: new G('store_unsolved_requests'),
103
+
104
+ stats() {
105
+ return {
106
+ send_counts: {
107
+ get: this.send_counts.get.get(),
108
+ upsert: this.send_counts.upsert.get(),
109
+ list: this.send_counts.list.get(),
110
+ delete: this.send_counts.delete.get()
111
+ },
112
+ recv_counts: {
113
+ get: this.recv_counts.get.get(),
114
+ upsert: this.recv_counts.upsert.get(),
115
+ list: this.recv_counts.list.get(),
116
+ delete: this.recv_counts.delete.get()
117
+ },
118
+ request_times: {
119
+ get: this.request_times.get.get(),
120
+ upsert: this.request_times.upsert.get(),
121
+ list: this.request_times.list.get(),
122
+ delete: this.request_times.delete.get()
123
+ },
124
+ request_errors: {
125
+ get: this.request_errors.get.get(),
126
+ upsert: this.request_errors.upsert.get(),
127
+ list: this.request_errors.list.get(),
128
+ delete: this.request_errors.delete.get()
129
+ },
130
+ batched_total_count: this.batched_total_count.get(),
131
+ batched_request_count: this.batched_request_count.get(),
132
+ unsolved_requests: this.unsolved_requests.get(),
133
+ average_request_time: {
134
+ get: this.request_times.get.get() / this.send_counts.get.get(),
135
+ upsert: this.request_times.upsert.get() / this.send_counts.upsert.get(),
136
+ list: this.request_times.list.get() / this.send_counts.list.get()
137
+ }
138
+ }
139
+ }
140
+ }
141
+
142
+ export const providerMetrics = {
143
+ hit_count: new C('provider_hit_count'),
144
+ miss_count: new C('provider_miss_count'),
145
+ queue_size: new G('provider_queue_size'),
146
+ total_duration: new C('provider_total_duration'),
147
+ total_queued: new C('provider_total_queued'),
148
+ stats() {
149
+ return {
150
+ hit_count: this.hit_count.get(),
151
+ miss_count: this.miss_count.get(),
152
+ queue_size: this.queue_size.get(),
153
+ total_duration: this.total_duration.get(),
154
+ total_queued: this.total_queued.get(),
155
+ average_queue_time: this.total_queued.get() / (this.hit_count.get() + this.miss_count.get()),
156
+ average_duration: this.total_duration.get() / (this.hit_count.get() + this.miss_count.get())
157
+ }
158
+ }
159
+ }
160
+
161
+ export const processMetrics = {
162
+ process_binding_count: new C('process_binding_count'),
163
+ process_binding_time: new C('process_binding_time'),
164
+ process_binding_error: new C('process_binding_error'),
165
+ process_ethcall_count: new C('process_ethcall_count'),
166
+ process_eventemit_count: new C('process_eventemit_count'),
167
+ process_metricrecord_count: new C('process_metricrecord_count'),
168
+ process_pricecall_count: new C('process_pricecall_count'),
169
+ process_template_count: new C('process_template_count'),
170
+ process_handler_duration: new G('process_handler_duration'),
171
+ processor_handler_duration: new H('processor_handler_duration'),
172
+ processor_rpc_duration: new H('processor_rpc_duration'),
173
+ processor_rpc_queue_duration: new H('processor_rpc_queue_duration'),
174
+ processor_template_instance_count: new C('process_template_instance_count'),
175
+ processor_worker_run_time: new C('processor_worker_run_time'),
176
+ processor_worker_wait_time: new C('processor_worker_wait_time'),
177
+ processor_worker_queue_size: new G('processor_worker_queue_size'),
178
+ processor_worker_completed: new C('processor_worker_completed'),
179
+ stats() {
180
+ return {
181
+ process_binding_count: this.process_binding_count.get(),
182
+ process_binding_time: this.process_binding_time.get(),
183
+ process_binding_error: this.process_binding_error.get(),
184
+ process_ethcall_count: this.process_ethcall_count.get(),
185
+ process_eventemit_count: this.process_eventemit_count.get(),
186
+ process_metricrecord_count: this.process_metricrecord_count.get(),
187
+ process_pricecall_count: this.process_pricecall_count.get(),
188
+ process_template_count: this.process_template_count.get(),
189
+ process_handler_duration: this.process_handler_duration.get(),
190
+ processor_handler_duration: this.processor_handler_duration.get(),
191
+ processor_rpc_duration: this.processor_rpc_duration.get(),
192
+ processor_rpc_queue_duration: this.processor_rpc_queue_duration.get(),
193
+ processor_template_instance_count: this.processor_template_instance_count.get(),
194
+ processor_worker_run_time: this.processor_worker_run_time.get(),
195
+ processor_worker_wait_time: this.processor_worker_wait_time.get(),
196
+ processor_worker_queue_size: this.processor_worker_queue_size.get(),
197
+ processor_worker_completed: this.processor_worker_completed.get()
198
+ }
199
+ }
200
+ }
201
+
202
+ export const metricsStorage = new AsyncLocalStorage<string>()