Compare commits

..

10 Commits

Author SHA1 Message Date
makotocc0107
f55deb0b67 [增添]增添了错误捕捉,避免页面报错显示 2024-10-10 16:38:56 +08:00
makotocc0107
b7bf85593f [修正]修正了supervisord模版书写 2024-10-10 16:38:56 +08:00
10908
ebfe98f87e [删除]去除了多余数据库映射 2024-10-10 16:29:39 +08:00
5eeb9deae4 [添加]prometheus远程提交时的数据源可以自己填写 2024-10-10 15:32:17 +08:00
makotocc0107
ec0420439d [修正]修正了各个服务中confd中的reload重启命令 2024-10-09 16:32:45 +08:00
10908
13467b75d2 [修改]数据映射 2024-10-09 16:29:58 +08:00
makotocc0107
f8dbe17c6a [修正]修正了当dhcp启用时保存的bug 2024-10-09 13:40:37 +08:00
makotocc0107
d422735062 [修改]优化了dns地址添加方法,增添了错误提示消息 2024-10-09 13:40:37 +08:00
makotocc0107
50ca69c958 [修改]实现读取DHCP模式并判断,优化service中读取方法 2024-10-09 13:40:37 +08:00
makotocc0107
d0b379eab1 [修改]修改并基本实现了网络配置功能 2024-10-09 13:40:37 +08:00
19 changed files with 464 additions and 131 deletions

52
data/etcd/etc/etcd.conf Normal file
View File

@@ -0,0 +1,52 @@
# [member]
ETCD_NAME=default
ETCD_DATA_DIR="/var/lib/etcd/default.etcd"
#ETCD_WAL_DIR=""
ETCD_SNAPSHOT_COUNT="10000"
#ETCD_HEARTBEAT_INTERVAL="100"
#ETCD_ELECTION_TIMEOUT="1000"
#ETCD_LISTEN_PEER_URLS="http://localhost:2380"
ETCD_LISTEN_CLIENT_URLS="http://localhost:2379"
#ETCD_MAX_SNAPSHOTS="5"
#ETCD_MAX_WALS="5"
#ETCD_CORS=""
#
#[cluster]
#ETCD_INITIAL_ADVERTISE_PEER_URLS="http://localhost:2380"
# if you use different ETCD_NAME (e.g. test), set ETCD_INITIAL_CLUSTER value for this name, i.e. "test=http://..."
#ETCD_INITIAL_CLUSTER="default=http://localhost:2380"
#ETCD_INITIAL_CLUSTER_STATE="new"
#ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster"
ETCD_ADVERTISE_CLIENT_URLS="http://localhost:2379"
#ETCD_DISCOVERY=""
#ETCD_DISCOVERY_SRV=""
#ETCD_DISCOVERY_FALLBACK="proxy"
#ETCD_DISCOVERY_PROXY=""
#ETCD_STRICT_RECONFIG_CHECK="false"
#ETCD_AUTO_COMPACTION_RETENTION="0"
#
#[proxy]
#ETCD_PROXY="off"
#ETCD_PROXY_FAILURE_WAIT="5000"
#ETCD_PROXY_REFRESH_INTERVAL="30000"
#ETCD_PROXY_DIAL_TIMEOUT="1000"
#ETCD_PROXY_WRITE_TIMEOUT="5000"
#ETCD_PROXY_READ_TIMEOUT="0"
#
#[security]
#ETCD_CERT_FILE=""
#ETCD_KEY_FILE=""
#ETCD_CLIENT_CERT_AUTH="false"
#ETCD_TRUSTED_CA_FILE=""
#ETCD_AUTO_TLS="false"
#ETCD_PEER_CERT_FILE=""
#ETCD_PEER_KEY_FILE=""
#ETCD_PEER_CLIENT_CERT_AUTH="false"
#ETCD_PEER_TRUSTED_CA_FILE=""
#ETCD_PEER_AUTO_TLS="false"
#
#[logging]
#ETCD_DEBUG="false"
# examples for -log-package-levels etcdserver=WARNING,security=DEBUG
#ETCD_LOG_PACKAGE_LEVELS=""

View File

@@ -0,0 +1,13 @@
global:
scrape_interval: 15s
scrape_configs:
- job_name: 'node_exporter'
scrape_interval: 10s
static_configs:
- targets: [ '127.0.0.1:9100' ]
- job_name: 'opcua_exporter'
scrape_interval: 10s
static_configs:
- targets: [ '127.0.0.1:8191' ]

View File

@@ -0,0 +1,20 @@
[supervisord]
nodaemon=true ; 让 supervisor 运行在前台,保持容器不退出
logfile=/var/log/supervisor/supervisord.log
pidfile=/var/run/supervisord.pid
[program:confd]
command=/usr/local/bin/confd -config-file /etc/confd/confd.toml
autostart=true
autorestart=true
stderr_logfile=/var/log/confd.err.log
stdout_logfile=/var/log/confd.out.log
[program:prometheus]
command=/usr/local/bin/prometheus --config.file=/etc/prometheus/prometheus.yml
autostart=true
autorestart=true
stderr_logfile=/var/log/prometheus.err.log
stdout_logfile=/var/log/prometheus.out.log

View File

@@ -5,8 +5,14 @@ services:
- 2379:2379
- 2380:2370
network_mode: host
volumes:
- ./data/etcd/data:/var/lib/etcd
- ./data/etcd/etc:/etc/etcd
prometheus:
build: docker/prometheus
volumes:
- ./data/prometheus/etc/prometheus:/etc/prometheus
- ./data/prometheus/etc/supervisord:/etc/supervisord
ports:
- 9090:9090
depends_on:
@@ -14,8 +20,9 @@ services:
network_mode: host
panel:
build: management-panel
# volumes:
# - ./management-panel:/app
volumes:
- ./data/panel/storage/app:/app/storage/app
- /var/run/dbus/system_bus_socket:/var/run/dbus/system_bus_socket
entrypoint: /app/entrypoint.sh
command: php artisan octane:start --server=swoole --workers=4 --host=0.0.0.0 --port=8000
ports:
@@ -25,6 +32,7 @@ services:
- prometheus
restart: always
network_mode: host
privileged: true
node-exporter:
build: docker/node_exporter
# privileged: true

View File

@@ -19,7 +19,8 @@ RUN dnf update -y \
# 设置环境变量
ENV ETCD_LISTEN_CLIENT_URLS="http://0.0.0.0:2379" \
ETCD_ADVERTISE_CLIENT_URLS="http://127.0.0.1:2379"
ETCD_ADVERTISE_CLIENT_URLS="http://127.0.0.1:2379" \
ETCD_DATA_DIR=/var/lib/etcd/
# 暴露端口
EXPOSE 2379 2380

View File

@@ -5,3 +5,4 @@ keys = [
"/time/",
"/remote_write/",
]
reload_cmd = "pkill -9 -f '/usr/local/bin/prometheus --config.file=/etc/prometheus/prometheus.yml'"

View File

@@ -4,3 +4,4 @@ dest = "/etc/supervisord/supervisord.conf"
keys = [
"/time/"
]
reload_cmd = "pkill -9 -f '/usr/local/bin/prometheus --config.file=/etc/prometheus/prometheus.yml'"

View File

@@ -11,6 +11,15 @@ scrape_configs:
scrape_interval: {{ getv "/time/opcua_scrape_interval"}}{{ getv "/time/opcua_scrape_interval_unit" }}
static_configs:
- targets: [ '127.0.0.1:8191' ]
labels:
__hostname__: {{ getv "/remote_write/data_source_label" }}
relabel_configs:
- source_labels:
- "__hostname__"
regex: (.*)
target_label: source
action: replace
replacement: {{ getv "/remote_write/data_source_label" }}
{{ if getv "/remote_write/state" }}
remote_write:
- url: {{ getv "/remote_write/url" }}

View File

@@ -11,7 +11,7 @@ stderr_logfile=/var/log/confd.err.log
stdout_logfile=/var/log/confd.out.log
[program:prometheus]
command=/usr/local/bin/prometheus --config.file=/etc/prometheus/prometheus.yml --storage.tsdb.retention.time={{ getv "/time/storage_interval"}}{{ getv "/time/storage_interval_unit")}}
command=/usr/local/bin/prometheus --config.file=/etc/prometheus/prometheus.yml --storage.tsdb.retention.time={{ getv "/time/storage_interval"}}{{ getv "/time/storage_interval_unit"}}
autostart=true
autorestart=true
stderr_logfile=/var/log/prometheus.err.log

View File

@@ -20,6 +20,7 @@ LOG_DEPRECATIONS_CHANNEL=null
LOG_LEVEL=debug
DB_CONNECTION=sqlite
DB_DATABASE=/app/storage/app/database.sqlite
# DB_HOST=127.0.0.1
# DB_PORT=3306
# DB_DATABASE=laravel

View File

@@ -6,10 +6,12 @@ use App\Services\NetworkService;
use App\Settings\NetworkSettings;
use Filament\Forms;
use Filament\Forms\Form;
use Filament\Notifications\Notification;
use Filament\Pages\SettingsPage;
use Filament\Forms\Components\TextInput;
use Filament\Forms\Components\Select;
use Filament\Forms\Components\Fieldset;
use Filament\Forms\Components\TagsInput;
class ManageNetwork extends SettingsPage
{
@@ -39,12 +41,21 @@ class ManageNetwork extends SettingsPage
// 当选择框的值更新时,自动填充对应的网络信息
if (isset($interfaces[$state])) {
$dhcp_status = NetworkService::getDHCPstatus($state);
$set('dhcp_enabled', $dhcp_status ? 'true':'false');
$set('ip', $interfaces[$state]['ip'] ?? '无IP地址');
$set('mask', $interfaces[$state]['mask'] ?? '无子网掩码');
// 假设我们通过其他方式获取网关(如手动输入或自动获取)
// $set('gateway', '自动获取或手动输入的值');
$set('gateway', $interfaces[$state]['gateway']);
// $set('dns_server_1', $interfaces[$state]['dns'][0] ?? null);
// $set('dns_server_2', $interfaces[$state]['dns'][1] ??
$set('dns_servers', $interfaces[$state]['dns'] ?? []);
error_log('state:' . $state);
error_log('dhcp_enabled: ' . $dhcp_status);
error_log("ip " . $interfaces[$state]['ip']);
error_log("mask " . $interfaces[$state]['mask']);
error_log("gateway " . $interfaces[$state]['gateway']);
error_log("dns_servers " . print_r($interfaces[$state]['dns'], true));
}
else{
error_log("未找到接口:" . $state);
@@ -54,58 +65,194 @@ class ManageNetwork extends SettingsPage
// 动态显示端口信息
Fieldset::make('端口信息')
->schema([
Select::make('dhcp_enabled')
->label('DHCP启用')
->options([
'true' => '是',
'false' => '否',
])
->reactive()
->required(), // 如果需要可以加上这个
TextInput::make('ip')
->label("IP地址")
->readOnly() // 禁用以表示这是自动填充的字段
->disabled(fn($get) => $get('dhcp_enabled') === 'true')
->required()
->reactive(),
TextInput::make('mask')
Select::make('mask')
->label('子网掩码')
->readOnly()
->options([
8 => "255.0.0.0 /8",
9 => "255.128.0.0 /9",
10 => "255.192.0.0 /10",
11 => "255.224.0.0 /11",
12 => "255.240.0.0 /12",
13 => "255.248.0.0 /13",
14 => "255.252.0.0 /14",
15 => "255.254.0.0 /15",
16 => "255.255.0.0 /16",
17 => "255.255.128.0 /17",
18 => "255.255.192.0 /18",
19 => "255.255.224.0 /19",
20 => "255.255.240.0 /20",
21 => "255.255.248.0 /21",
22 => "255.255.252.0 /22",
23 => "255.255.254.0 /23",
24 => "255.255.255.0 /24",
25 => "255.255.255.128 /25",
26 => "255.255.255.192 /26",
27 => "255.255.255.224 /27",
28 => "255.255.255.240 /28",
29 => "255.255.255.248 /29",
30 => "255.255.255.252 /30",
31 => "255.255.255.254 /31",
32 => "255.255.255.255 /32",
])
->required()
->disabled(fn($get) => $get('dhcp_enabled') === 'true')
->reactive(),
TextInput::make('gateway')
->label('网关')
->disabled(fn($get) => $get('dhcp_enabled') === 'true'),
TagsInput::make('dns_servers')
->label('DNS地址')
->disabled(fn($get) => $get('dhcp_enabled') === 'true')
->reactive()
->afterStateUpdated(function ($state, callable $set) {
// 保留合法的DNS地址
$validDns = array_filter($state, function ($dns) {
// 验证是否是合法的IPv4地址
return filter_var($dns, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4);
});
// 如果有非法的DNS地址显示提示并移除它们
if (count($validDns) !== count($state)) {
Notification::make()
->title('无效的DNS地址 已自动移除')
->warning() // 设置消息类型为警告
->send();
}
// 限制最多只能有3个合法的DNS地址
if (count($validDns) > 3) {
$validDns = array_slice($validDns, 0, 3);
Notification::make()
->title('最多只能输入3个DNS地址')
->warning()
->send();
}
// 更新字段状态
$set('dns_servers', $validDns);
})
])
->visible(fn($get) => !is_null($get('network_interface'))) // 检查是否有选择的接口
->reactive(),
// DHCP选项
Select::make('dhcp_enabled')
->options([
true => "",
false => ""
])
->default(false)
->label("DHCP启用")
->required()
->reactive(),
// 动态显示的网络信息字段
Fieldset::make('网络配置')
->schema([
TextInput::make('ip_address')
->label("IP地址")
->placeholder('如127.0.0.1')
->required(),
TextInput::make('subnet_mask')
->label('子网掩码')
->placeholder('如255.255.255.0')
->required(),
TextInput::make('gateway')
->label('网关')
->placeholder('如192.168.1.1')
->required(),
TextInput::make('dns_server_1')
->label('DNS地址')
->placeholder('如6.6.6.6')
->required(),
TextInput::make('dns_server_2')
->label('DNS备用地址')
->placeholder('如114.114.114.114')
->required(),
])
->visible(fn($get) => in_array($get('dhcp_enabled'), [false])),
]);
}
public function save(): void
{
// 获取用户输入的网络配置
$ipAddress = $this->form->getState()['ip'] ?? '';
$gateway = $this->form->getState()['gateway'] ?? '';
$dhcpEnabled = $this->form->getState()['dhcp_enabled'];
if ($dhcpEnabled !== 'true'){
if (!filter_var($ipAddress, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) {
Notification::make()
->title('无效的 IP 地址格式')
->warning()
->send();
return; // 返回,不执行保存操作
}
// 验证网关地址格式
if (!filter_var($gateway, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) {
Notification::make()
->title('无效的网关地址格式')
->warning()
->send();
return; // 返回,不执行保存操作
}
}
// 验证 IP 地址格式
// 调用父类的保存方法以持久化设置
parent::save();
// 保存后执行终端命令
$this->executeCommands();
}
protected function executeCommands(): void
{
// 获取用户输入的网络配置
$networkInterface = $this->form->getState()['network_interface'] ?? '';
$dhcpEnabled = $this->form->getState()['dhcp_enabled'];
error_log('接口名称:' . $networkInterface);
error_log('dhcp' . $dhcpEnabled);
$ipAddress = $this->form->getState()['ip'] ?? '';
$mask = $this->form->getState()['mask'] ?? '';
$gateway = $this->form->getState()['gateway'] ?? '';
$dnsServers = $this->form->getState()['dns_servers'] ?? [];
$dnsString = implode(',', $dnsServers); // 合并 DNS 地址为字符串
if ($dhcpEnabled=='true') {
// 如果启用 DHCP设置为使用 DHCP
$commands = [
"nmcli con mod '$networkInterface' ipv4.method auto ipv4.addresses \"\" ipv4.gateway \"\" ipv4.dns \"\"",
"nmcli con down '$networkInterface'",
"nmcli con up '$networkInterface'"
];
foreach ($commands as $command) {
$output = [];
$returnVar = 0;
exec($command, $output, $returnVar);
// 记录输出和返回状态以便调试
error_log("命令: $command");
error_log("输出: " . implode("\n", $output));
error_log("返回状态: $returnVar");
// 如果需要,处理错误
if ($returnVar !== 0) {
error_log("执行命令出错: $command");
}
}
} else {
// 根据接口和用户输入构建命令
$commands = [
"nmcli con mod '$networkInterface' ipv4.method manual ipv4.addresses $ipAddress/$mask ipv4.gateway $gateway ipv4.dns $dnsString",
"nmcli con down '$networkInterface'",
"nmcli con up '$networkInterface'", // 重新激活连接
];
foreach ($commands as $command) {
$output = [];
$returnVar = 0;
exec($command, $output, $returnVar);
// 记录输出和返回状态以便调试
error_log("命令: $command");
error_log("输出: " . implode("\n", $output));
error_log("返回状态: $returnVar");
// 如果需要,处理错误
if ($returnVar !== 0) {
error_log("执行命令出错: $command");
}
}
}
}
}

View File

@@ -13,6 +13,10 @@ class ManageRemoteWrite extends SettingsPage
protected static string $settings = RemoteWriteSettings::class;
protected static ?string $navigationLabel = '远程写入配置管理';
protected static ?string $title = '远程写入配置管理';
public function form(Form $form): Form
{
return $form
@@ -32,6 +36,11 @@ class ManageRemoteWrite extends SettingsPage
->url()
->placeholder("http://remote-storage.example.com/api/v1/write"),
// 数据源名陈
Forms\Components\TextInput::make('data_source_label')
->label("数据源名称")
->required(),
// 每个分片的最大队列容量
Forms\Components\TextInput::make('queue_config_capacity')
->label("队列容量")

View File

@@ -13,49 +13,78 @@ class SystemStats extends BaseWidget
{
$prometheus = new PrometheusService();
try {
// 获取内存总量
$memoryTotalQuery = 'node_memory_MemTotal_bytes';
$memoryTotalResult = $prometheus->query($memoryTotalQuery);
$memoryTotal = $memoryTotalResult['data']['result'][0]['value'][1] ?? 0;
} catch (\Exception $e) {
error_log('Failed to retrieve memory total: ' . $e->getMessage());
$memoryTotal = 0;
}
try {
// 获取已用内存
$memoryAvailableQuery = 'node_memory_MemAvailable_bytes';
$memoryAvailableResult = $prometheus->query($memoryAvailableQuery);
$memoryAvailable = $memoryAvailableResult['data']['result'][0]['value'][1] ?? 0;
} catch (\Exception $e) {
error_log('Failed to retrieve memory available: ' . $e->getMessage());
$memoryAvailable = 0;
}
$memoryUsed = $memoryTotal - $memoryAvailable;
$memoryDisplay = round($memoryUsed / (1024 * 1024 * 1024), 2) . ' GB / ' . round($memoryTotal / (1024 * 1024 * 1024), 2) . ' GB';
try {
// 获取硬盘总量
$diskTotalQuery = 'node_filesystem_size_bytes{fstype!="rootfs",fstype!="tmpfs",fstype!="squashfs",mountpoint=~"/|/home|/boot"}';
$diskTotalResult = $prometheus->query($diskTotalQuery);
$diskTotal = array_sum(array_map(function ($item) {
return $item['value'][1] ?? 0;
}, $diskTotalResult['data']['result']));
} catch (\Exception $e) {
error_log('Failed to retrieve disk total: ' . $e->getMessage());
$diskTotal = 0;
}
try {
// 获取已用硬盘
$diskFreeQuery = 'node_filesystem_free_bytes{fstype!="rootfs",fstype!="tmpfs",fstype!="squashfs",mountpoint=~"/|/home|/boot"}';
$diskFreeResult = $prometheus->query($diskFreeQuery);
$diskFree = array_sum(array_map(function ($item) {
return $item['value'][1] ?? 0;
}, $diskFreeResult['data']['result']));
} catch (\Exception $e) {
error_log('Failed to retrieve disk free: ' . $e->getMessage());
$diskFree = 0;
}
$diskUsed = $diskTotal - $diskFree;
$diskDisplay = round($diskUsed / (1024 * 1024 * 1024), 2) . ' GB / ' . round($diskTotal / (1024 * 1024 * 1024), 2) . ' GB';
try {
// 获取系统启动时间
$uptimeQuery = 'node_boot_time_seconds';
$uptimeResult = $prometheus->query($uptimeQuery);
$bootTime = $uptimeResult['data']['result'][0]['value'][1] ?? 0;
} catch (\Exception $e) {
error_log('Failed to retrieve boot time: ' . $e->getMessage());
$bootTime = 0;
}
$uptime = now()->timestamp - $bootTime;
$uptimeDisplay = gmdate('H:i:s', $uptime);
try {
// 获取CPU核心数量
$cpuCoresQuery = 'count(node_cpu_seconds_total{mode="system"})';
$cpuCoresResult = $prometheus->query($cpuCoresQuery);
$cpuCores = $cpuCoresResult['data']['result'][0]['value'][1] ?? 0;
} catch (\Exception $e) {
error_log('Failed to retrieve CPU cores: ' . $e->getMessage());
$cpuCores = 0;
}
return [
BaseWidget\Stat::make('内存占用', $memoryDisplay),
@@ -65,6 +94,7 @@ class SystemStats extends BaseWidget
];
}
protected function getPollingInterval(): ?string
{
return "1s";

View File

@@ -19,28 +19,23 @@ class MetricWidgetChart extends InlineChartWidget
protected function getData(): array
{
$prometheus = new PrometheusService();
$labels = [];
$data = [];
try {
$query1 = $this->record->name . '{data="real"}';
$start = now()->now()->subMinutes(2)->timestamp;
$start = now()->subMinutes(2)->timestamp;
$end = now()->timestamp;
$step = 5;
// 查询 Prometheus 数据
$realdata = $prometheus->queryRange($query1, $start, $end, $step);
// 检查查询结果是否有数据
if (empty($realdata['data']['result'])) {
// 如果没有数据,返回一个空数据集或提示信息
return [
'labels' => [],
'datasets' => [],
];
}
if (!empty($realdata['data']['result']) && !empty($realdata['data']['result'][0]['values'][1])) {
if (!empty($realdata['data']['result'][0]['values'][1])) {
// 获取内存使用率数据
// 获取数据
$realdataValue = array_column($realdata['data']['result'][0]['values'], 1, 0);
// 只保留最新的 MAX_POINTS 个数据点
@@ -48,15 +43,20 @@ class MetricWidgetChart extends InlineChartWidget
$timestamps = array_slice($timestamps, -self::MAX_POINTS);
foreach ($timestamps as $timestamp) {
$labels[] = date('H:i:s', $timestamp); // 格式化时间戳为小时:分钟:秒
$data[] = round(floatval($realdataValue[$timestamp]), 2); // 取出每个时间点的内存使用率,并保留两位小数
$labels[] = date('H:i:s', $timestamp); // 格式化时间戳
$data[] = round(floatval($realdataValue[$timestamp]), 2); // 保留两位小数
}
}
} catch (\Exception $e) {
error_log('Failed to retrieve data from Prometheus: ' . $e->getMessage());
// 处理错误,返回默认的空数据集或提示信息
return [
'labels' => [],
'datasets' => [],
];
}
// 将数据格式化为 InlineChartWidget 所需的格式
// $formattedRealData = $this->formatData($realdata, 'Real Data');
// 返回格式化后的数据
return [
'labels' => $labels,
'datasets' => [

View File

@@ -6,8 +6,8 @@ class NetworkService
{
public static function getNetworkInterfaces()
{
// 使用 `ifconfig` 来获取接口和 IP 地址
$output = shell_exec('ifconfig');
// 使用 `nmcli dev show` 来获取接口信息
$output = shell_exec('nmcli dev show');
return self::parseNetworkInfo($output);
}
@@ -19,20 +19,30 @@ class NetworkService
foreach ($lines as $line) {
// 匹配接口名称
if (preg_match('/^([a-zA-Z0-9-]+): flags=/', $line, $matches)) {
$interface = $matches[1];
if (preg_match('/^GENERAL.DEVICE: *(.+)$/', $line, $matches)) {
$interface = trim($matches[1]);
$interfaces[$interface] = [
'ip' => null,
'mask' => null,
'gateway' => null,
'dns' => [],
];
}
// 匹配 IPv4 地址
if ($interface && preg_match('/inet ([\d\.]+)/', $line, $matches)) {
$interfaces[$interface]['ip'] = $matches[1];
if ($interface && preg_match('/IP4.ADDRESS\[1\]: *([\d\.]+)\/(\d+)/', $line, $matches)) {
$ip = $matches[1];
$prefix = $matches[2];
// $mask = self::prefixToMask($prefix); // 获取子网掩码
$interfaces[$interface]['ip'] = $ip;
$interfaces[$interface]['mask'] = $prefix; // 设置掩码格式
}
// 匹配子网掩码
if ($interface && preg_match('/netmask ([\d\.]+)/', $line, $matches)) {
$interfaces[$interface]['mask'] = $matches[1];
// 匹配网关
if ($interface && preg_match('/IP4.GATEWAY: *([\d\.]+)/', $line, $matches)) {
$interfaces[$interface]['gateway'] = $matches[1];
}
// 匹配 DNS
if ($interface && preg_match('/IP4.DNS\[\d+\]: *([\d\.]+)/', $line, $matches)) {
$interfaces[$interface]['dns'][] = $matches[1];
}
}
@@ -42,4 +52,19 @@ class NetworkService
return $interfaces;
}
public static function getDHCPstatus($state)
{
// 调试:检查传递的 state 参数
error_log("正在获取DHCP状态的接口: " . $state);
// 执行 nmcli 命令,获取指定连接的详细信息
$output = shell_exec('nmcli con show ' . escapeshellarg($state));
// 使用正则表达式匹配 'ipv4.method: auto'
if (preg_match('/ipv4\.method:\s+auto/', $output)) {
return true; // 如果匹配到,说明启用了 DHCP
} else {
return false; // 否则未启用 DHCP
}
}
}

View File

@@ -21,11 +21,18 @@ class PrometheusService
*/
public function query($query)
{
try {
$response = $this->client->get('query', [
'query' => ['query' => $query],
]);
return json_decode($response->getBody()->getContents(), true);
} catch (\Exception $e) {
// 处理异常,记录日志或返回错误信息
error_log('Query failed: ' . $e->getMessage());
return ['error' => 'Failed to execute query', 'message' => $e->getMessage()];
}
}
/**
* 执行 Prometheus 区间查询
@@ -38,6 +45,7 @@ class PrometheusService
*/
public function queryRange($query, $start, $end, $step)
{
try {
$response = $this->client->get('query_range', [
'query' => [
'query' => $query,
@@ -47,7 +55,13 @@ class PrometheusService
],
]);
return json_decode($response->getBody()->getContents(), true);
} catch (\Exception $e) {
// 处理异常,记录日志或返回错误信息
error_log('Query range failed: ' . $e->getMessage());
return ['error' => 'Failed to execute query range', 'message' => $e->getMessage()];
}
}
/**
* 获取 Prometheus 监控的所有目标

View File

@@ -9,6 +9,7 @@ class RemoteWriteSettings extends Settings
public bool $state;
public string $auth_mode;
public string $url;
public ?string $data_source_label;
public int $queue_config_capacity;
public int $queue_config_max_samples_per_send;
public string $queue_config_batch_send_deadline;

View File

@@ -11,6 +11,7 @@ return new class extends SettingsMigration
// 添加 Prometheus remote_write 配置参数
$this->migrator->add('remote_write.url', 'http://remote-storage.example.com/api/v1/write'); // 远程存储的URL
$this->migrator->add('remote_write.data_source_label',); // 数据源名称
$this->migrator->add('remote_write.queue_config_capacity', 10000); // 每个分片的最大队列容量
$this->migrator->add('remote_write.queue_config_max_samples_per_send', 2000); // 每次发送的最大样本数
$this->migrator->add('remote_write.queue_config_batch_send_deadline', '5s'); // 每次发送批次的最大等待时间

View File

@@ -6,5 +6,5 @@ keys = [
"/exporter/",
"/metrics/",
]
reload_cmd = "pkill -f opcua-exporter"
reload_cmd = "pkill -f opcua_exporter"