ASR_BASE
Change-Id: Icf3719cc0afe3eeb3edc7fa80a2eb5199ca9dda1
diff --git a/external/subpack/utils/prometheus-node-exporter-ucode/files/extra/dnsmasq.uc b/external/subpack/utils/prometheus-node-exporter-ucode/files/extra/dnsmasq.uc
new file mode 100644
index 0000000..3644b20
--- /dev/null
+++ b/external/subpack/utils/prometheus-node-exporter-ucode/files/extra/dnsmasq.uc
@@ -0,0 +1,6 @@
+const x = ubus.call("dnsmasq", "metrics");
+if (!x)
+ return false;
+
+for (let i in x)
+ gauge(`dnsmasq_${i}_total`)(null, x[i]);
diff --git a/external/subpack/utils/prometheus-node-exporter-ucode/files/extra/ltq-dsl.uc b/external/subpack/utils/prometheus-node-exporter-ucode/files/extra/ltq-dsl.uc
new file mode 100644
index 0000000..1644497
--- /dev/null
+++ b/external/subpack/utils/prometheus-node-exporter-ucode/files/extra/ltq-dsl.uc
@@ -0,0 +1,72 @@
+const x = ubus.call("dsl", "metrics");
+
+if (!x)
+ return false;
+
+gauge("dsl_info")({
+ atuc_vendor: x.atu_c.vendor,
+ atuc_system_vendor: x.atu_c.system_vendor,
+ chipset: x.chipset,
+ firmware_version: x.firmware_version,
+ api_version: x.api_version,
+ driver_version: x.driver_version,
+}, 1);
+
+gauge("dsl_line_info")({
+ annex: x.annex,
+ standard: x.standard,
+ mode: x.mode,
+ profile: x.profile,
+}, 1);
+
+gauge("dsl_up")({ detail: x.state }, x.up);
+gauge("dsl_uptime_seconds")(null, x.uptime);
+
+gauge("dsl_line_attenuation_db")
+ ({ direction: "down" }, x.downstream.latn)
+ ({ direction: "up" }, x.upstream.latn);
+gauge("dsl_signal_attenuation_db")
+ ({ direction: "down" }, x.downstream.satn)
+ ({ direction: "up" }, x.upstream.satn);
+gauge("dsl_signal_to_noise_margin_db")
+ ({ direction: "down" }, x.downstream.snr)
+ ({ direction: "up" }, x.upstream.snr);
+gauge("dsl_aggregated_transmit_power_db")
+ ({ direction: "down" }, x.downstream.actatp)
+ ({ direction: "up" }, x.upstream.actatp);
+
+if (x.downstream.interleave_delay)
+ gauge("dsl_latency_seconds")
+ ({ direction: "down" }, x.downstream.interleave_delay / 1000000.0)
+ ({ direction: "up" }, x.upstream.interleave_delay / 1000000.0);
+gauge("dsl_datarate")
+ ({ direction: "down" }, x.downstream.data_rate)
+ ({ direction: "up" }, x.upstream.data_rate);
+gauge("dsl_max_datarate")
+ ({ direction: "down" }, x.downstream.attndr)
+ ({ direction: "up" }, x.upstream.attndr);
+
+counter("dsl_error_seconds_total")
+ ({ err: "forward error correction", loc: "near" }, x.errors.near.fecs)
+ ({ err: "forward error correction", loc: "far" }, x.errors.far.fecs)
+ ({ err: "errored", loc: "near" }, x.errors.near.es)
+ ({ err: "errored", loc: "far" }, x.errors.far.es)
+ ({ err: "severely errored", loc: "near" }, x.errors.near.ses)
+ ({ err: "severely errored", loc: "far" }, x.errors.far.ses)
+ ({ err: "loss of signal", loc: "near" }, x.errors.near.loss)
+ ({ err: "loss of signal", loc: "far" }, x.errors.far.loss)
+ ({ err: "unavailable", loc: "near" }, x.errors.near.uas)
+ ({ err: "unavailable", loc: "far" }, x.errors.far.uas);
+
+counter("dsl_errors_total")
+ ({ err: "header error code error", loc: "near" }, x.errors.near.hec)
+ ({ err: "header error code error", loc: "far" }, x.errors.far.hec)
+ ({ err: "non pre-emptive crc error", loc: "near" }, x.errors.near.crc_p)
+ ({ err: "non pre-emptive crc error", loc: "far" }, x.errors.far.crc_p)
+ ({ err: "pre-emptive crc error", loc: "near" }, x.errors.near.crcp_p)
+ ({ err: "pre-emptive crc error", loc: "far" }, x.errors.far.crcp_p);
+
+if (x.erb)
+ counter("dsl_erb_total")
+ ({ counter: "sent" }, x.erb.sent)
+ ({ counter: "discarded" }, x.erb.discarded);
diff --git a/external/subpack/utils/prometheus-node-exporter-ucode/files/extra/netstat.uc b/external/subpack/utils/prometheus-node-exporter-ucode/files/extra/netstat.uc
new file mode 100644
index 0000000..7449305
--- /dev/null
+++ b/external/subpack/utils/prometheus-node-exporter-ucode/files/extra/netstat.uc
@@ -0,0 +1,30 @@
+function parse(fn) {
+ let f = fs.open(fn);
+
+ if (!f)
+ return false;
+
+ let names, values;
+ while (names = nextline(f), values = nextline(f)) {
+ const name = wsplit(names);
+ const value = wsplit(values);
+
+ if (name[0] != value[0])
+ continue;
+
+ if (length(name) != length(value))
+ continue;
+
+ let prefix = substr(name[0], 0, -1);
+ for (let i = 1; i < length(name); i++)
+ gauge(`node_netstat_${prefix}_${name[i]}`)(null, value[i]);
+ }
+
+ return true;
+}
+
+let n = parse("/proc/net/netstat");
+let s = parse("/proc/net/snmp");
+
+if (!n && !s)
+ return false;
diff --git a/external/subpack/utils/prometheus-node-exporter-ucode/files/extra/openwrt.uc b/external/subpack/utils/prometheus-node-exporter-ucode/files/extra/openwrt.uc
new file mode 100644
index 0000000..10c15a1
--- /dev/null
+++ b/external/subpack/utils/prometheus-node-exporter-ucode/files/extra/openwrt.uc
@@ -0,0 +1,14 @@
+const x = ubus.call("system", "board");
+
+if (!x)
+ return false;
+
+gauge("node_openwrt_info")({
+ board_name: x.board_name,
+ id: x.release.distribution,
+ model: x.model,
+ release: x.release.version,
+ revision: x.release.revision,
+ system: x.system,
+ target: x.release.target,
+}, 1);
diff --git a/external/subpack/utils/prometheus-node-exporter-ucode/files/extra/snmp6.uc b/external/subpack/utils/prometheus-node-exporter-ucode/files/extra/snmp6.uc
new file mode 100644
index 0000000..d440a88
--- /dev/null
+++ b/external/subpack/utils/prometheus-node-exporter-ucode/files/extra/snmp6.uc
@@ -0,0 +1,23 @@
+function parse(fn, device, skipdecl) {
+ let f = fs.open(fn);
+
+ if (!f)
+ return false;
+
+ const labels = { device };
+ let line;
+ while (line = nextline(f)) {
+ const x = wsplit(line);
+
+ if (length(x) < 2)
+ continue;
+
+ counter(`snmp6_${x[0]}`, null, skipdecl)(labels, x[1]);
+ }
+}
+
+parse("/proc/net/snmp6", "all");
+
+const root = "/proc/net/dev_snmp6/";
+for (let device in fs.lsdir(root))
+ parse(root + device, device, true);
diff --git a/external/subpack/utils/prometheus-node-exporter-ucode/files/extra/uci_dhcp_host.uc b/external/subpack/utils/prometheus-node-exporter-ucode/files/extra/uci_dhcp_host.uc
new file mode 100644
index 0000000..0d55724
--- /dev/null
+++ b/external/subpack/utils/prometheus-node-exporter-ucode/files/extra/uci_dhcp_host.uc
@@ -0,0 +1,14 @@
+import { cursor } from "uci";
+
+const uci = cursor();
+uci.load("dhcp");
+
+let m = gauge("dhcp_host_info");
+
+uci.foreach('dhcp', `host`, (s) => {
+ m({
+ name: s.name,
+ mac: s.mac,
+ ip: s.ip,
+ }, 1);
+});
diff --git a/external/subpack/utils/prometheus-node-exporter-ucode/files/extra/wifi.uc b/external/subpack/utils/prometheus-node-exporter-ucode/files/extra/wifi.uc
new file mode 100644
index 0000000..fb46b55
--- /dev/null
+++ b/external/subpack/utils/prometheus-node-exporter-ucode/files/extra/wifi.uc
@@ -0,0 +1,121 @@
+import { request, 'const' as wlconst } from 'nl80211';
+
+const x = ubus.call("network.wireless", "status");
+
+if (!x)
+ return false;
+
+const iftypes = [
+ "Unknown",
+ "Ad-Hoc",
+ "Client",
+ "Master",
+ "Master (VLAN)",
+ "WDS",
+ "Monitor",
+ "Mesh Point",
+ "P2P Client",
+ "P2P Go",
+ "P2P Device",
+ "OCB",
+];
+
+let m_radio_info = gauge("wifi_radio_info");
+let m_network_info = gauge("wifi_network_info");
+let m_network_quality = gauge("wifi_network_quality");
+let m_network_bitrate = gauge("wifi_network_bitrate");
+let m_network_noise = gauge("wifi_network_noise_dbm");
+let m_network_signal = gauge("wifi_network_signal_dbm");
+let m_stations_total = counter("wifi_stations_total");
+let m_station_inactive = gauge("wifi_station_inactive_milliseconds");
+let m_station_rx_bytes = counter("wifi_station_receive_bytes_total");
+let m_station_tx_bytes = counter("wifi_station_transmit_bytes_total");
+let m_station_rx_packets = counter("wifi_station_receive_packets_total");
+let m_station_tx_packets = counter("wifi_station_transmit_packets_total");
+let m_station_signal = gauge("wifi_station_signal_dbm");
+let m_station_rx_bitrate = gauge("wifi_station_receive_kilobits_per_second");
+let m_station_tx_bitrate = gauge("wifi_station_transmit_kilobits_per_second");
+let m_station_exp_tp = gauge("wifi_station_expected_throughput_kilobits_per_second");
+
+for (let radio in x) {
+ const rc = x[radio]["config"];
+
+ m_radio_info({
+ radio,
+ htmode: rc["htmode"],
+ channel: rc["channel"],
+ country: rc["country"],
+ } ,1);
+
+ for (let iface in x[radio]["interfaces"]) {
+ const ifname = iface["ifname"];
+ const nc = iface["config"];
+ const wif = request(wlconst.NL80211_CMD_GET_INTERFACE, 0, { dev: ifname });
+
+ if (!wif)
+ continue;
+
+ m_network_info({
+ radio,
+ ifname,
+ ssid: nc["ssid"] || nc["mesh_id"],
+ bssid: wif["mac"],
+ mode: iftypes[wif["iftype"]],
+ }, 1);
+
+ const wsta = request(wlconst.NL80211_CMD_GET_STATION, wlconst.NLM_F_DUMP, { dev: ifname });
+ let signal = 0;
+ let bitrate = 0;
+ const stations = length(wsta) || 0;
+ if (stations) {
+ for (let sta in wsta) {
+ signal += sta["sta_info"].signal;
+ bitrate += sta["sta_info"]["tx_bitrate"].bitrate32;
+ }
+ bitrate /= stations * 0.01;
+ signal /= stations;
+ }
+
+ let labels = { radio, ifname };
+ m_network_bitrate(labels, bitrate || NaN);
+ m_network_signal(labels, signal || NaN);
+ m_network_quality(labels, signal ? 100.0 / 70 * (signal + 110) : NaN);
+
+ const wsur = request(wlconst.NL80211_CMD_GET_SURVEY, wlconst.NLM_F_DUMP, { dev: ifname });
+ let noise = 0;
+ for (let i in wsur) {
+ if (i["survey_info"]["frequency"] != wif["wiphy_freq"])
+ continue;
+
+ noise = i["survey_info"]["noise"];
+ break;
+ }
+
+ m_network_noise(labels, noise || NaN);
+
+ if (config["stations"] != "1")
+ continue;
+
+ m_stations_total(labels, stations);
+ if (!stations)
+ continue;
+
+ for (let sta in wsta) {
+ labels["mac"] = sta["mac"];
+ const info = sta["sta_info"];
+
+ m_station_inactive(labels, info["inactive_time"]);
+ m_station_rx_bytes(labels, info["rx_bytes64"]);
+ m_station_tx_bytes(labels, info["tx_bytes64"]);
+ m_station_rx_packets(labels, info["rx_packets"]);
+ m_station_tx_packets(labels, info["tx_packets"]);
+ m_station_signal(labels, info["signal"]);
+ if (info["rx_bitrate"] && info["rx_bitrate"]["bitrate32"])
+ m_station_rx_bitrate(labels, info["rx_bitrate"]["bitrate32"] * 100);
+ if (info["tx_bitrate"] && info["tx_bitrate"]["bitrate32"])
+ m_station_tx_bitrate(labels, info["tx_bitrate"]["bitrate32"] * 100);
+ if (info["expected_throughput"])
+ m_station_exp_tp(labels, info["expected_throughput"]);
+ }
+ }
+}
diff --git a/external/subpack/utils/prometheus-node-exporter-ucode/files/extra/wireguard.uc b/external/subpack/utils/prometheus-node-exporter-ucode/files/extra/wireguard.uc
new file mode 100644
index 0000000..12ae56a
--- /dev/null
+++ b/external/subpack/utils/prometheus-node-exporter-ucode/files/extra/wireguard.uc
@@ -0,0 +1,49 @@
+import { cursor } from "uci";
+
+const x = ubus.call("wireguard", "status");
+if (!x)
+ return false;
+
+const uci = cursor();
+uci.load("network");
+
+let m_wg_iface_info = gauge("wireguard_interface_info");
+let m_wg_peer_info = gauge("wireguard_peer_info");
+let m_wg_handshake = gauge ("wireguard_latest_handshake_seconds");
+let m_wg_rx = gauge ("wireguard_received_bytes_total");
+let m_wg_tx = gauge ("wireguard_sent_bytes_total");
+
+for (let iface in x) {
+ const wc = x[iface];
+
+ m_wg_iface_info({
+ name: iface,
+ public_key: wc["public_key"],
+ listen_port: wc["listen_port"],
+ fwmark: wc["fwmark"] || NaN,
+ }, 1);
+
+ for (let peer in wc["peers"]) {
+ let description;
+ uci.foreach('network', `wireguard_${iface}`, (s) => {
+ if (s.public_key == peer)
+ description = s.description;
+ });
+
+ const pc = wc["peers"][peer];
+
+ m_wg_peer_info({
+ interface: iface,
+ public_key: peer,
+ description,
+ endpoint: pc["endpoint"],
+ persistent_keepalive_interval: pc["persistent_keepalive_interval"] || NaN,
+ }, 1);
+
+ const labels = { public_key: peer };
+
+ m_wg_handshake(labels, pc["last_handshake"]);
+ m_wg_rx(labels, pc["rx_bytes"]);
+ m_wg_tx(labels, pc["tx_bytes"]);
+ }
+}