Open
[feat]: 支持可观测gauge仪表 #104
zhangyuxian3Add on 28 days ago
[feat]: 支持可观测gauge仪表 #104
Open
Total: 7 files changed+33-74
| @@ -2,7 +2,7 @@ | |||
| 2 | "name": "observability", | 2 | "name": "observability", |
| 3 | "type": "application", | 3 | "type": "application", |
| 4 | "deployConfig": "om_priv.service", | 4 | "deployConfig": "om_priv.service", |
| 5 | - "version": "1.90.35", | 5 | + "version": "1.90.36", |
| 6 | "author": "Huawei", | 6 | "author": "Huawei", |
| 7 | "license": "Mulan PSL v2", | 7 | "license": "Mulan PSL v2", |
| 8 | "description": " ", | 8 | "description": " ", |
| @@ -26,7 +26,7 @@ | |||
| 26 | "conan": "mdb_interface/[>=1.80.1]" | 26 | "conan": "mdb_interface/[>=1.80.1]" |
| 27 | }, | 27 | }, |
| 28 | { | 28 | { |
| 29 | - "conan": "opentelemetry/1.13.0.018" | 29 | + "conan": "opentelemetry/1.13.0.019" |
| 30 | } | 30 | } |
| 31 | ] | 31 | ] |
| 32 | }, | 32 | }, |
| @@ -182,74 +182,21 @@ class SharedHistogram { | |||
| 182 | std::mutex m_mutex; | 182 | std::mutex m_mutex; |
| 183 | }; | 183 | }; |
| 184 | 184 | ||
| 185 | -// 辅助函数:比较两个AttributeMap是否相等 | ||
| 186 | -static bool attributes_equal(const AttributeMap &a, const AttributeMap &b) | ||
| 187 | -{ | ||
| 188 | - if (a.size() != b.size()) { | ||
| 189 | - return false; | ||
| 190 | - } | ||
| 191 | - for (const auto &pair : a) { | ||
| 192 | - auto it = b.find(pair.first); | ||
| 193 | - if (it == b.end()) { | ||
| 194 | - return false; | ||
| 195 | - } | ||
| 196 | - if (!Utils::AttributeValueEqual<nostd::string_view>(it->second, pair.second) && | ||
| 197 | - !Utils::AttributeValueEqual<int64_t>(it->second, pair.second) && | ||
| 198 | - !Utils::AttributeValueEqual<double>(it->second, pair.second) && | ||
| 199 | - !Utils::AttributeValueEqual<bool>(it->second, pair.second)) { | ||
| 200 | - return false; | ||
| 201 | - } | ||
| 202 | - } | ||
| 203 | - return true; | ||
| 204 | -} | ||
| 205 | - | ||
| 206 | class SharedGauge { | 185 | class SharedGauge { |
| 207 | public: | 186 | public: |
| 208 | - SharedGauge(nostd::shared_ptr<metrics_api::ObservableInstrument> observable_gauge) | 187 | + SharedGauge(nostd::unique_ptr<metrics_api::Gauge<double>> gauge) |
| 209 | - : m_observable_gauge(std::move(observable_gauge)) | 188 | + : m_gauge(std::move(gauge)) |
| 210 | { | 189 | { |
| 211 | - // 注册回调函数,返回所有存储的值(每个属性标签组合对应一个值) | ||
| 212 | - auto callback_func = [](metrics_api::ObserverResult observer, void *state) { | ||
| 213 | - SharedGauge *gauge = static_cast<SharedGauge *>(state); | ||
| 214 | - if (!gauge) { | ||
| 215 | - return; | ||
| 216 | - } | ||
| 217 | - | ||
| 218 | - if (absl::holds_alternative<opentelemetry::nostd::shared_ptr<metrics_api::ObserverResultT<double>>>(observer)) { | ||
| 219 | - auto result_ptr = | ||
| 220 | - absl::get<opentelemetry::nostd::shared_ptr<metrics_api::ObserverResultT<double>>>(observer); | ||
| 221 | - auto &result = *result_ptr; | ||
| 222 | - // 返回所有存储的值,每个属性标签组合对应一个值 | ||
| 223 | - std::lock_guard<std::mutex> guard(gauge->m_mutex); | ||
| 224 | - for (const auto &entry : gauge->m_values) { | ||
| 225 | - // 调用Observe时传入值和对应的属性标签 | ||
| 226 | - result.Observe(entry.second, entry.first); | ||
| 227 | - } | ||
| 228 | - } | ||
| 229 | - }; | ||
| 230 | - m_observable_gauge->AddCallback(callback_func, this); | ||
| 231 | } | 190 | } |
| 232 | 191 | ||
| 233 | void Record(double value, AttributeMap &attributes) | 192 | void Record(double value, AttributeMap &attributes) |
| 234 | { | 193 | { |
| 235 | std::lock_guard<std::mutex> guard(m_mutex); | 194 | std::lock_guard<std::mutex> guard(m_mutex); |
| 236 | - // 查找是否已存在相同的属性标签组合 | 195 | + m_gauge->Record(value, attributes); |
| 237 | - for (auto &entry : m_values) { | ||
| 238 | - if (attributes_equal(entry.first, attributes)) { | ||
| 239 | - // 如果找到相同的属性标签组合,更新值 | ||
| 240 | - entry.second = value; | ||
| 241 | - return; | ||
| 242 | - } | ||
| 243 | - } | ||
| 244 | - // 如果没有找到,添加新的条目 | ||
| 245 | - m_values.push_back(std::make_pair(attributes, value)); | ||
| 246 | } | 196 | } |
| 247 | 197 | ||
| 248 | private: | 198 | private: |
| 249 | - nostd::shared_ptr<metrics_api::ObservableInstrument> m_observable_gauge; | 199 | + nostd::unique_ptr<metrics_api::Gauge<double>> m_gauge; |
| 250 | - // 存储每个属性标签组合对应的值 | ||
| 251 | - // 使用vector存储,因为AttributeMap不能直接作为map的key(没有比较操作符) | ||
| 252 | - std::vector<std::pair<AttributeMap, double>> m_values; | ||
| 253 | std::mutex m_mutex; | 200 | std::mutex m_mutex; |
| 254 | }; | 201 | }; |
| 255 | 202 | ||
| @@ -322,10 +269,8 @@ public: | |||
| 322 | if (iter != gauge_map.end()) { | 269 | if (iter != gauge_map.end()) { |
| 323 | return iter->second; | 270 | return iter->second; |
| 324 | } | 271 | } |
| 325 | - // 基于ObservableGauge创建同步Gauge | 272 | + nostd::unique_ptr<metrics_api::Gauge<double>> m = m_meter->CreateDoubleGauge(name, description, unit); |
| 326 | - nostd::shared_ptr<metrics_api::ObservableInstrument> observable_gauge = | 273 | + nostd::shared_ptr<SharedGauge> n = nostd::shared_ptr<SharedGauge>(new SharedGauge(std::move(m))); |
| 327 | - m_meter->CreateDoubleObservableGauge(name, description, unit); | ||
| 328 | - nostd::shared_ptr<SharedGauge> n = nostd::shared_ptr<SharedGauge>(new SharedGauge(observable_gauge)); | ||
| 329 | gauge_map.insert(std::pair<std::string, nostd::shared_ptr<SharedGauge>>(name.data(), n)); | 274 | gauge_map.insert(std::pair<std::string, nostd::shared_ptr<SharedGauge>>(name.data(), n)); |
| 330 | return n; | 275 | return n; |
| 331 | } | 276 | } |
| @@ -38,6 +38,16 @@ function observability_client:OnAssemblyPropertiesChanged(cb) | |||
| 38 | 'bmc.kepler.Assembly', {'HostName'}) | 38 | 'bmc.kepler.Assembly', {'HostName'}) |
| 39 | end | 39 | end |
| 40 | 40 | ||
| 41 | +function observability_client:OnCertificatePropertiesChanged(cb) | ||
| 42 | + self.signal_slots[#self.signal_slots + 1] = subscribe_signal.on_properties_changed(self:get_bus(), '/bmc', cb, | ||
| 43 | + 'bmc.kepler.CertificateService.Certificate', {'FilePath'}) | ||
| 44 | +end | ||
| 45 | + | ||
| 46 | +function observability_client:OnCertificateInterfacesRemoved(cb) | ||
| 47 | + self.signal_slots[#self.signal_slots + 1] = subscribe_signal.on_interfaces_removed(self:get_bus(), '/bmc', cb, | ||
| 48 | + 'bmc.kepler.CertificateService.Certificate') | ||
| 49 | +end | ||
| 50 | + | ||
| 41 | function observability_client:GetDashboardObservabilityTracesObject() | 51 | function observability_client:GetDashboardObservabilityTracesObject() |
| 42 | return { | 52 | return { |
| 43 | SamplingRate = 0.5, | 53 | SamplingRate = 0.5, |
| @@ -16,7 +16,6 @@ local skynet = require 'skynet' | |||
| 16 | require 'skynet.manager' | 16 | require 'skynet.manager' |
| 17 | require 'observability.json_types.Receiver' | 17 | require 'observability.json_types.Receiver' |
| 18 | local log = require 'mc.logging' | 18 | local log = require 'mc.logging' |
| 19 | -local utils = require 'mc.utils' | ||
| 20 | local mdb = require 'mc.mdb' | 19 | local mdb = require 'mc.mdb' |
| 21 | local dbus = require 'sd_bus' | 20 | local dbus = require 'sd_bus' |
| 22 | local lu = require 'luaunit' | 21 | local lu = require 'luaunit' |
| @@ -43,13 +42,15 @@ end | |||
| 43 | local function clear_test_data(exit_test) | 42 | local function clear_test_data(exit_test) |
| 44 | log:info('clear test data') | 43 | log:info('clear test data') |
| 45 | local test_data_dir = skynet.getenv('TEST_DATA_DIR') | 44 | local test_data_dir = skynet.getenv('TEST_DATA_DIR') |
| 46 | - if not exit_test then return utils.remove_file(test_data_dir) end | 45 | + -- 目录内含持久化 db 文件,utils.remove_file 无法删除非空目录,用 rm -rf 保证清理生效 |
| 46 | + if not exit_test then return os.execute('rm -rf "' .. test_data_dir .. '"') end | ||
| 47 | 47 | ||
| 48 | skynet.timeout(0, function() | 48 | skynet.timeout(0, function() |
| 49 | skynet.sleep(20) | 49 | skynet.sleep(20) |
| 50 | + -- 先清理测试数据再退出进程:skynet.abort 会直接结束进程, | ||
| 51 | + -- 放在 abort 之后的清理永远不会执行,残留的持久化数据会导致下次运行断言失败 | ||
| 52 | + os.execute('rm -rf "' .. test_data_dir .. '" /tmp/test_dump') | ||
| 50 | skynet.abort() | 53 | skynet.abort() |
| 51 | - utils.remove_file(test_data_dir) | ||
| 52 | - utils.remove_file('/tmp/test_dump') | ||
| 53 | end) | 54 | end) |
| 54 | end | 55 | end |
| 55 | 56 | ||
| @@ -10,4 +10,4 @@ | |||
| 10 | 10 | ||
| 11 | require 'test_otel.test_logs' | 11 | require 'test_otel.test_logs' |
| 12 | require 'test_otel.test_trace' | 12 | require 'test_otel.test_trace' |
| 13 | --- require 'test_otel.test_metrics' | 13 | +require 'test_otel.test_metrics' |
| @@ -272,14 +272,14 @@ | |||
| 272 | "name": "bmc.system.uptime", | 272 | "name": "bmc.system.uptime", |
| 273 | "description": "BMC系统已经运行的时间", | 273 | "description": "BMC系统已经运行的时间", |
| 274 | "unit": "s", | 274 | "unit": "s", |
| 275 | - "type": "Counter", | 275 | + "type": "Gauge", |
| 276 | "attributes": [] | 276 | "attributes": [] |
| 277 | }, | 277 | }, |
| 278 | { | 278 | { |
| 279 | "name": "bmc.system.cpu.usage", | 279 | "name": "bmc.system.cpu.usage", |
| 280 | "description": "BMC CPU的使用情况", | 280 | "description": "BMC CPU的使用情况", |
| 281 | "unit": "percent", | 281 | "unit": "percent", |
| 282 | - "type": "UpDownCounter", | 282 | + "type": "Gauge", |
| 283 | "attributes": [ | 283 | "attributes": [ |
| 284 | { | 284 | { |
| 285 | "name": "cpu.mode", | 285 | "name": "cpu.mode", |
| @@ -293,7 +293,7 @@ | |||
| 293 | "name": "bmc.system.memory.usage", | 293 | "name": "bmc.system.memory.usage", |
| 294 | "description": "BMC使用的物理内存", | 294 | "description": "BMC使用的物理内存", |
| 295 | "unit": "By", | 295 | "unit": "By", |
| 296 | - "type": "UpDownCounter", | 296 | + "type": "Gauge", |
| 297 | "attributes": [ | 297 | "attributes": [ |
| 298 | { | 298 | { |
| 299 | "name": "system.memory.usage", | 299 | "name": "system.memory.usage", |
| @@ -307,7 +307,7 @@ | |||
| 307 | "name": "bmc.process.cpu.usage", | 307 | "name": "bmc.process.cpu.usage", |
| 308 | "description": "BMC进程CPU的使用情况", | 308 | "description": "BMC进程CPU的使用情况", |
| 309 | "unit": "percent", | 309 | "unit": "percent", |
| 310 | - "type": "UpDownCounter", | 310 | + "type": "Gauge", |
| 311 | "attributes": [ | 311 | "attributes": [ |
| 312 | { | 312 | { |
| 313 | "name": "process.name", | 313 | "name": "process.name", |
| @@ -321,7 +321,7 @@ | |||
| 321 | "name": "bmc.process.memory.usage", | 321 | "name": "bmc.process.memory.usage", |
| 322 | "description": "BMC进程使用的物理内存", | 322 | "description": "BMC进程使用的物理内存", |
| 323 | "unit": "By", | 323 | "unit": "By", |
| 324 | - "type": "UpDownCounter", | 324 | + "type": "Gauge", |
| 325 | "attributes": [ | 325 | "attributes": [ |
| 326 | { | 326 | { |
| 327 | "name": "process.name", | 327 | "name": "process.name", |
| @@ -349,7 +349,7 @@ | |||
| 349 | "name": "bmc.system.flash.lifeleft", | 349 | "name": "bmc.system.flash.lifeleft", |
| 350 | "description": "BMC Flash的剩余寿命", | 350 | "description": "BMC Flash的剩余寿命", |
| 351 | "unit": "percent", | 351 | "unit": "percent", |
| 352 | - "type": "UpDownCounter", | 352 | + "type": "Gauge", |
| 353 | "attributes": [] | 353 | "attributes": [] |
| 354 | } | 354 | } |
| 355 | ] | 355 | ] |