@emartech/telemetry-javascript

中文文档
1.5.2发布于 2024/04/04MITTypeScriptESM + CJS近 30 天下载 5780

使用 Typescript/ Javascript 代码的遥测包

中文使用文档
文档目录10 节
  1. 遥测客户端库
  2. 快速启动
  3. 特征
  4. 建议使用
  5. 量子生成
  6. 大型多模块应用程序
  7. 高级使用
  8. 将计量法纳入共同编码
  9. 计量类型
  10. 方法

遥测-地理特征

遥测客户端库

通过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的默认名称空间模块.
  • metrics
    • client ( 默认 : “ 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等).

直方图的可视化

Histogram chart with intervals of 100 showing numerous observations in each interval.

实例
  • 收到的请求的大小
  • 每个电子邮件中的个性化符号数
/*
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'
);    

版本与发布记录

@emartech/telemetry-javascript 共发布 16 个版本,首次发布于 2022/05/24;过去 12 个月发布了 0 个版本。

版本发布日期距今
2.0.0-rc.12024/04/112 年前
1.5.2latest2024/04/042 年前
2.0.0-rc.02024/03/272 年前
1.5.12023/01/263 年前
1.5.02023/01/213 年前
1.4.02023/01/143 年前

关于 @emartech/telemetry-javascript 的常见问题

@emartech/telemetry-javascript 是什么?

使用 Typescript/ Javascript 代码的遥测包

如何安装 @emartech/telemetry-javascript?

在项目目录运行 npm install @emartech/telemetry-javascript,或使用 pnpm add / yarn add / bun add。

@emartech/telemetry-javascript 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@emartech/telemetry-javascript 支持 ESM 还是 CommonJS?

同时提供 ES Module 与 CommonJS 入口,import 和 require() 都可以使用,打包工具会自动选择合适的版本。

@emartech/telemetry-javascript 需要什么版本的 Node.js?

package.json 的 engines 字段要求 Node.js >=12.0.0。版本不符时 npm 默认只给出警告,开启 engine-strict 后会拒绝安装。

@emartech/telemetry-javascript 可以商用吗?

@emartech/telemetry-javascript 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@emartech/telemetry-javascript 的下载量有多少?

根据 npm 官方下载统计,@emartech/telemetry-javascript 在 2026/10/14 – 2026/11/12 这 30 天内被下载 5,780 次,日均约 193 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@emartech/telemetry-javascript 还在维护吗?

最新版本 1.5.2 发布于 2024/04/04(2 年前);至今共发布 16 个版本,其中过去 12 个月发布了 0 个;首次发布于 2022/05/24。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。