Metric Lua API

模块: local mc = require("mc") → mc.metric

概述

mc.metric 把 mc::engine 的同步度量句柄暴露给 Lua:按 catalog 创建 Counter / UpDownCounter / Gauge / Histogram,add/record 写入进程 SHM。不提供独立 collect;诊断用 debug_dump。

主要特性

  • 与 C++ mc::engine::create_* / apply_metric_config 同一套单例与 catalog
  • 无效句柄仍是 userdata,is_valid() 为 false,打点返回 false
  • Enabled=false 或未激活时 add/record 返回 true(空操作)
  • 属性可用 Lua table 或 mc.dict

基本用法

local mc = require("mc")

mc.metric.apply_config("Enabled", true)
mc.metric.apply_config("ServiceName", "bmc.app")

local c = mc.metric.create_counter("bmc.app.requests", "http requests", "1")
assert(c:is_valid())
assert(c:add(1, { method = "GET" }))
assert(not c:add(-1, { method = "GET" }))

local g = mc.metric.create_gauge("bmc.app.temp", "temp", "C")
assert(g:record(36.5))

local snap = mc.metric.debug_dump()
assert(type(snap) == "table")
assert(snap.magic == 0x4D434D53)
local mc = require("mc")
mc.metric.apply_config("Enabled", true)
mc.metric.apply_config("ActivatedMetrics", { "bmc.app.temp" })

local c = mc.metric.create_counter("bmc.app.requests")
-- 句柄仍 valid,但未激活:add 为 true 且不改槽
assert(c:add(1, { method = "GET" }))

API 详细说明

create_counter / create_updown_counter / create_gauge / create_histogram

h = mc.metric.create_counter(name[, description[, unit]])
h = mc.metric.create_updown_counter(name[, description[, unit]])
h = mc.metric.create_gauge(name[, description[, unit]])
h = mc.metric.create_histogram(name[, description[, unit]])

参数:

参数 类型 说明
name string catalog 中的仪器名
description string 可选;非空时须与 catalog 一致
unit string 可选;非空时须与 catalog 一致

返回值: userdata 句柄(永不 nil)

异常: name 非 string 时 Lua 参数错误

创建走 mc::engine::create_*:lazy 加载默认 catalog。未登记、kind 不符、Observable 已跳过 → is_valid()==false。

apply_config

ok = mc.metric.apply_config(key, value)

参数:

参数 类型 说明
key string Enabled / ServiceName / ActivatedMetrics / ExportIntervalSeconds
value bool / string / number / string 数组 与 C++ apply_metric_config 相同

返回值: 参数形态合法为 true,否则 false(不抛)

异常: 无(类型不对返回 false)

mc.metric.apply_config("Enabled", true)
mc.metric.apply_config("ExportIntervalSeconds", 40)
mc.metric.apply_config("ActivatedMetrics", { "bmc.app.temp" })

debug_dump

snap = mc.metric.debug_dump()

返回值: SHM 已 map 且 magic 已发布时为 table,否则 nil

异常: 不抛异常

table 结构:

字段 说明
magic 0x4D434D53
meters 数组
meters[i].name meter 名
meters[i].overflow_drops 溢出丢弃
meters[i].series 序列数组
series.name / kind / attrs 仪器名、种类、属性表
series.value Counter / UpDown
series.gauge Gauge
series.count / sum / min / max / buckets Histogram;buckets 为 1-based 数组

同名同属性可能有多条(段未 unlink 时旧槽仍在)。断言当前进程写入值时取 最后一条。

POSIX 文件:/dev/shm/mc_metrics。

句柄方法

counter / updown_counter :add

ok = handle:add(value[, attrs])
参数 类型 说明
value number Counter 须 ≥0 的整数语义;UpDown 可为负
attrs table 或 dict 可选

返回值: boolean。无效句柄或校验失败 false;开关关闭或未激活 true。

gauge / histogram :record

ok = handle:record(value[, attrs])

NaN / Inf → false。Histogram 桶只来自 catalog。

:is_valid

ok = handle:is_valid()

最佳实践

✅ 正例

local c = mc.metric.create_counter("bmc.app.requests")
if c:is_valid() then
    c:add(1, mc.dict({ method = "GET" }))
end
-- 关 Enabled 后仍 add,不崩溃
mc.metric.apply_config("Enabled", false)
assert(c:add(1, { method = "GET" }))

❌ 反例

-- 不要假设 io.open("/dev/shm/mc.metrics")
local f = io.open("/dev/shm/mc.metrics", "rb")
-- dump 取第一条可能是上次进程留下的槽
local snap = mc.metric.debug_dump()
local first = snap.meters[1].series[1]
assert(first.gauge == 36.5)  -- 可能是旧值 40

相关文档