遥测-地理特征
遥测客户端库
通过StatsD向OpenTelometer收集器提供遥测的图书馆.
快速启动
设置
环境变量( 可选)
TELEMETRY_CONFIG = {
'application':'personalization service',
'domain':'personalization',
'module':'compilation',
'metrics': {
'client':'statsd',
'hostname':'127.0.0.1',
'port':8125,
'enabled':true
}
}
application(默认:"'"):应用程序使用库.domain(默认:"'"):应用程序的默认名称空间域.module(默认:"'"):applcation的默认名称空间模块.metricsclient( 默认 : “ statsd ” ):statsd要使用的计量客户端.hostname(默认值: “ 127. 0.0.1 ”) : 计量客户端将发送计量数据的宿主。 如果在 Docker 本地运行, 这将成为收藏服务的名称 .- 示例
services: app: environment: - 'TELEMETRY_CONFIG={"metrics":{"hostname":"collector"}}'
- 示例
port(default: 8125): 度量衡客户端将发送度量衡数据的端口.enabled(默认: 真) :true|false控制是否释放 medris.
安装
安装 Emarsys 遥测包
npm install @emartech/telemetry-javascript
写出你的第一个度量
import * as metrics from '@emartech/telemetry-javascript';
// With default namespace set
metrics.setDefaultNamespace('personalization', 'compilation');
metrics.incrementCounter('request_count');
特征
-
使用密码 OpenTeleometry-兼容度量衡 拥有谷歌云监测的既定路径
-
使用框外默认值 自动接入Emarsys OpenTeleometry管道
-
将您的应用程序代码与更改隔开 到 OpenTeleometer 或遥测数据平台
-
自动 抓取函数的持续时间
metrics.setDefaultNamespace('personalization', 'compilation');
// Callable
const personalizationString = metrics.time(
'total_duration',
[500, 1000, 1500, 2000, 2500, 3000, 3500, 4000]],
{ 'attribute1': 'value1', 'attribute2': 'value2' },
computePersonalizationString,
'Hello <name>',
'<name>',
'World!',
);
function computePersonalizationString(
personlizationString: string,
token: string,
tokenValue: string): string {
return personalizationString.replace(token, tokenValue);
}
/*
Result: 'Hello World!'
Metric Name: personalization_compilation_total_duration
Value: Time to execute function in milliseconds
*/
// Decorator
const myClass = new MyClass();
const result = myClass.computePersonalizationString('Hello <name>', '<name>', 'World!');
class MyClass {
@metrics.timeDecorator('total_duration')
function computePersonalizationString(
personlizationString: string,
token: string,
tokenValue: string): string {
return personalizationString.replace(token, tokenValue);
}
}
/*
Result: 'Hello World!'
Metric Name: personalization_compilation_total_duration
Value: Time to execute function in milliseconds
*/
- 自动 记录函数的持续时间和可靠性
metrics.setDefaultNamespace('personalization', 'compilation');
// Callable
// Success
const personalizationString = 'Hello <name>';
const token ='<name>';
const tokenValue = 'World!'
const result = metrics.timeAndCount(
'total',
() => {
computePersonalizationString(personalizationString, token, tokenValue);
},
[500, 1000, 1500, 2000, 2500, 3000, 3500, 4000]],
{ 'attribute1': 'value1', 'attribute2': 'value2' },
);
// OR
const result = metrics.metricWrapper(
'total',
[500, 1000, 1500, 2000, 2500, 3000, 3500, 4000]],
{ 'attribute1': 'value1', 'attribute2': 'value2' },
computePersonalizationString,
'Hello <name>',
'<name>',
'World!',
);
function computePersonalizationString(
personlizationString: string,
token: string,
tokenValue: string): string {
return personalizationString.replace(token, tokenValue);
}
/*
Result: 'Hello World!'
Metric Name: personalization_compilation_total_duration
Value: Time to execute function in milliseconds
Auto-Attribute: 'success:true'
Metric Name: personalization_compilation_total_count
Value: Time to execute function in milliseconds
Auto-Attribute: 'success:true'
*/
metrics.setDefaultNamespace('personalization', 'compilation');
// Failure
const personalizationString = 'Hello <name>';
const token ='<name>';
const tokenValue = 'World!'
const result = metrics.timeAndCount(
'total',
() => {
computePersonalizationString(personalizationString, token, tokenValue);
},
[500, 1000, 1500, 2000, 2500, 3000, 3500, 4000]],
{ 'attribute1': 'value1', 'attribute2': 'value2' },
);
// OR
const personalizationString = metrics.metricWrapper(
'total',
[500, 1000, 1500, 2000, 2500, 3000, 3500, 4000]],
{ 'attribute1': 'value1', 'attribute2': 'value2' },
computePersonalizationString,
'Hello <name>',
'<name>',
'World!',
);
function computePersonalizationString(
personlizationString: string,
token: string,
tokenValue: string): string {
throw new Error();
}
/*
Result: Error
Metric Name: personalization_compilation_total_duration
Value: Time to execute function in milliseconds
Auto-Attribute: 'success:false'
Metric Name: personalization_compilation_total_count
Value: Time to execute function in milliseconds
Auto-Attribute: 'success:false'
*/
// Decorator
const myClass = new MyClass();
const result = myClass.computePersonalizationString('Hello <name>', '<name>', 'World!');
class MyClass {
@metrics.timeAndCountDecorator('total')
function computePersonalizationString(
personlizationString: string,
token: string,
tokenValue: string): string {
return personalizationString.replace(token, tokenValue);
}
}
/*
Result: 'Hello World!'
Metric Name: personalization_compilation_total_duration
Value: Time to execute function in milliseconds
Auto-Attribute: 'success:true'
Metric Name: personalization_compilation_total_count
Value: Time to execute function in milliseconds
Auto-Attribute: 'success:true'
*/
- 命名空间度量单位 模块、组件或其他标准
const compilationNamespace = metrics.getNamespace(domain='personalization', module='compilation');
compilationNamespace.recordTimer('total_duration', 1000);
// Metric Name: personalization_compilation_total_duration
const executionNamespace = metrics.getNamespace(domain='personalization', module='execution');
executionNamespace.recordTimer('total_duration', 1000);
// Metric Name: personalization_execution_total_duration
- 弹性 任何范围内的标记度量 在不附加配置的情况下将元数据添加到您的衡量标准
// Global attribute
metrics.setAttribute('hostname', 'server4');
// Namespace attribute
const compilationNamespace = metrics.getNamespace('personalization', 'compilation');
compilationNamespace.setAttribute('worker_type', 'reticulator');
// Dynamic attribute
const compilationNamespace = metrics.getNamespace('personalization', 'compilation');
compilationNamespace.incrementCounter(
'completedJobs_count',
{ 'attribute1': 'value1', 'attribute2': 'value2' }
);
- 在共享代码中添加衡量标准, 并看到它们独立地在消耗应用程序中报告
建议使用
应用程序启动
import * as metrics from '@emartech/telemetry-javascript';
// We will use a single namespace to cover all of the metrics generated by our application, so we set it up as the default.
metrics.setDefaultNamespace('personalization', 'compilation');
metrics.incrementCounter('total_duration');
// We will explicitly create our metrics in order to provide a description and unit for our metrics
metrics.createCounter('request_Count', 'Number of requests the service received', 'requests');
metrics.createGauge('queue_depth', 'Number of requests currently in the queue', 'requests');
量子生成
// Application code - throughout the application, metrics will be generated
import * as metrics from '@emartech/telemetry-javascript';
def process_incoming_request(request):
metrics.increment_counter('total_requests')
generated_error = handle_request()
if generated_error:
metrics.increment_counter('error_requests')
大型多模块应用程序
import * as metrics from '@emartech/telemetry-javascript';
// Namespace objects can be created and stored at the module, component, or other level to create separate units for metrics
const compilationNamespace = metrics.getNamespace('personalization', 'compilation');
compilationNamespace.incrementCounter('request_count');
const executionNamespace = metrics.getNamespace('personalization', 'execution');
executionNamespace.incrementCounter('request_count');
高级使用
import * as metrics from '@emartech/telemetry-javascript';
// For each default entity or setting, the deftaults can overriden by using lower-level APIs.
metrics.setDefaultClient(new StatsDClient('endpoint', 0));
metrics.setAttribute('hostname', 'server4');
const compilationNamespace = metrics.getNamespace('personalization', 'compilation');
compilationNamespace.setAttribute('namespace_attribute', 'foo');
const totalDurationMetric = compilationNamespace.createTimer('total_duration', 'Total duration of blah', 'ms');
totalDurationMetric.setAttribute('metric_attribute', 'bar');
totalDurationMetric.record(
1000,
[200, 400, 600, 800, 1000, 1200, 1400],
{ 'attribute1': 'value1', 'attribute2': 'value2' }
);
将计量法纳入共同编码
import * as metrics from '@emartech/telemetry-javascript';
// When instrumenting a shared library, the shared library should create it's own namespace and write it's metrics there.
// The shared library will rely upon the consuming application to attach any attributes it want's applied to the data to the default metric client.
compilationSharedLibraryNamespace = metrics.getNamespace('personalization', 'compilation_shared_library');
compilationSharedLibraryNamespace.createCounter('compilation_invocations', 'Number of compilation invocations', 'invocations');
compilationSharedLibraryNamespace.incrementCounter('compilation_invocations');
计量类型
Emarsys遥测图书馆支持四种计量方法:
- 柜台
- 计时器
- 高地语
- 直方图
计数器
反计量标准可以随时间而递增或减少,并记录所有提供值的总(和).
实例
- 处理的信息数量
- 产生错误的数目
/*
incrementCounter(
metricName: string,
value = 1,
attributes: Record<string, string> = {},
): void;
*/
metrics.incrementCounter(
'request_count',
100,
{ 'attribute1': 'value1', 'attribute2': 'value2' }
);
高盖
一个度量衡存储了所观测到的东西的当前值。 Gauge 度量衡应用于不合理加起来的数据,而是取而代之的是新的度量衡.
在一个时间间隔(一般为每60个)中写入的测量表的最后一个值覆盖了以前的任何值.
实例
- 队列中的项目数量
- 当前进程内存使用情况
/*
recordGauge(
metricName: string,
value: number,
attributes: Record<string, string> = {},
): void;
*/
metrics.recordGauge(
'queue_depth',
100000,
{ 'attribute1': 'value1', 'attribute2': 'value2' }
);
直方图
直方图计量存储在一个时间间隔内记录的多值的统计摘要。 记录的每一项观察都计入一系列“桶”中,这些桶被配置成直方图。 这种存储方法允许在收集后计算统计数据,如以后的最低,最高,中位数和百分位数(P99等).
直方图的可视化

实例
- 收到的请求的大小
- 每个电子邮件中的个性化符号数
/*
recordHistogram(
metricName: string,
value: number,
buckets: number[] = [0, 5, 10, 25, 50, 75, 100, 250, 500, 1000],
attributes: Record<string, string> = {},
): void;
*/
metrics.recordHistogram(
'total_size',
2500,
[1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000, 9000, 10000],
{ 'attribute1': 'value1', 'attribute2': 'value2' },
);
计时器
一个定时器度量法可以捕捉同一代码或过程的多点观测所经过的时间,并导致这些时间值的分布. 可以处理分布,以确定中位值,P99或其他感兴趣的值.
计时器是"直方图"计量的特例,可以存储任何类型数据的统计分布.
实例
- 处理信件所需时间
- 运行数据库查询所需的时间
/*
recordTimer(
metricName: string,
value: number,
buckets: number[] = [0, 10, 25, 50, 75, 100, 250, 500, 1000, 5000, 10000, 30000, 60000, 240000],
attributes: Record<string, string> = {},
): void;
*/
metrics.recordTimer(
'total_duration',
850,
[100, 200, 300, 400, 500, 600, 700, 800, 900, 1000],
{ 'attribute1': 'value1', 'attribute2': 'value2' }
);
方法
Emarsys 遥测图书馆提供实用方法
切入到下熔层
连字符串被转换成骆驼拼接字符串, 用于 GCP 属性字段
/*
toLowerCamelCase(
name: string | undefined
): string
*/
metrics.Util.toLowerCamelCase(
'telemetry-attribute-example'
);