Run monitoring physical devices on devstack

本文介绍了如何在OpenStack中集成SNMP和IPMI来监控物理设备,包括路由器、交换机等,并详细说明了安装、配置及使用步骤。同时,通过DevStack环境实现了对硬件资源如CPU、内存、磁盘和网络状态的监控,并介绍了如何监控资源健康数据如风扇速度、电压和温度。最后,展示了如何通过Ceilometer服务收集和存储这些监控数据。

From “Icehouse” release on Openstack has been added monitoring physical devices. At this moment available only one inspector – SNMP Inspector. IPMI Inspector will be add soon.

1. SNMP data:

The SNMP Inspector monitors devices such as routers, switches etc. The basis for this is the Net-SNMP (snmpd) package. The SNMP Inspector supports such meters as:

  • hardware.cpu – cpu stats, average value for CPU load (1, 5, 15 min)
  • hardware.memory – memory stats, total and used
  • hardware.disk – disk stats, list of all disks with total and used size for each
  • hardware.network – network stats, list of IP’s with bandwidth, incoming, outgoing bytes and outgoing errors

The snmpd (a Linux Daemon) running on resources sends data to the SNMP Inspector directly.

  1.  Install snmpd on your machine:
    sudo apt-get install snmpd
  2. Change /etc/snmp/snmpd.conf to make sure that snmpd daemon will be able  get all necessary data:
    rocommunity public 
    syslocation "ICClab"
    syscontact serh@zhaw.ch
    sysservices 79
    proc
    disk / 15%
    disk /usr/backup 15%
  3. Restart snmpd
  4. Download devstack:
    git clone https://github.com/openstack-dev/devstack.git
  5. Enable ceilometer services in devstack/localrc:
    # Enable the ceilometer metering services
    enable_service ceilometer-acompute 
    ceilometer-acentral ceilometer-anotification 
    ceilometer-collector
    
    # Enable the ceilometer api services
    enable_service ceilometer-api
  6. Run devstack:
    ./devstack/stack.ch
  7. Add meters to /etc/ceilometer/pipeline.yaml:
       ...
        - name: meter_snmp
          interval: 600
          resources:
              - snmp://localhost
          meters:
              - "hardware.cpu*"
              - "hardware.memory*"
              - "hardware.disk*"
              - "hardware.network*"
          sinks:
              - meter_sink
        ...
  8. Rerun Ceilometer central agent
    celometer-agent-central

now you can check meters:Screenshot from 2014-07-01 11:27:05and samples:Screenshot from 2014-07-01 11:30:53 for such meters as hardware.disk and hardware.network in database has been stored additional information. IP, MAC, Name for network stats and device, path for disk.

database

2. IPMI Inspector

The IPMI Inspector monitors resource health data including:

  • current.value – current value of fan speed, voltage, temperature
  • max.value – maximum available value of stats
  • min.value – minimum available value of stats
  • current.status – status fan, voltage, temperature (ok/fail)
  1. Install ipmitool on your machine:
    sudo apt-get  install ipmitool
  2. Enable ironic services in devstack/localrc:
    # Enable Ironic API and Ironic Conductor
    enable_service ir-api
    enable_service ir-cond
  3. Add line to /etc/ironic/ironic.conf:
    send_sensor_data=true
  4. Rerun ironic conductor:
    ironic-conductor
  5. Create node which support ipmi driver:
    ironic node-create -d pxe_ipmitool -i ipmi_address=ip.mi.add.ress
    -i ipmi_password=password -i ipmi_username=username
  6. Add meters to /etc/ceilometer/pipeline.yaml:
       ...
        - name: meter_ipmi
          interval: 600
          resources:
              - ipmi://ip.mi.add.ress
          meters:
              - "hardware.rpm*"
              - "hardware.volt*"
              - "hardware.degree*"
          sinks:
              - meter_sink
        ...
  7. Rerun Ceilometer central agent
    celometer-agent-central
内容概要:本文档是一份关于交换路由配置的学习笔记,系统地介绍了网络设备的远程管理、交换机与路由器的核心配置技术。内容涵盖Telnet、SSH、Console三种远程控制方式的配置方法;详细讲解了VLAN划分原理及Access、Trunk、Hybrid端口的工作机制,以及端口镜像、端口汇聚、端口隔离等交换技术;深入解析了STP、MSTP、RSTP生成树协议的作用与配置步骤;在路由部分,涵盖了IP地址配置、DHCP服务部署(接口池与全局池)、NAT转换(静态与动态)、静态路由、RIP与OSPF动态路由协议的配置,并介绍了策略路由和ACL访问控制列表的应用;最后简要说明了华为防火墙的安全区域划分与基本安全策略配置。; 适合人群:具备一定网络基础知识,从事网络工程、运维或相关技术岗位1-3年的技术人员,以及准备参加HCIA/CCNA等认证考试的学习者。; 使用场景及目标:①掌握企业网络中常见的交换与路由配置技能,提升实际操作能力;②理解VLAN、STP、OSPF、NAT、ACL等核心技术原理并能独立完成中小型网络搭建与调试;③通过命令示例熟悉华为设备CLI配置逻辑,为项目实施和故障排查提供参考。; 阅读建议:此笔记以实用配置为主,建议结合模拟器(如eNSP或Packet Tracer)动手实践每一条命令,对照拓扑理解数据流向,重点关注VLAN间通信、路由选择机制、安全策略控制等关键环节,并注意不同设备型号间的命令差异。
using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Net; using System.Net.NetworkInformation; using System.Net.Sockets; using System.Runtime.InteropServices; using System.Threading; using System.Threading.Tasks; public class GenICamCameraMonitor { // 相机状态枚举 public enum CameraStatus { Disconnected, Connected, Streaming, Error } // 事件:相机状态变化 public event Action<CameraStatus, CameraInfo> OnStatusChanged; // 相机信息结构 public struct CameraInfo { public string CameraModel; public string CameraSerial; public IPAddress IPAddress; public PhysicalAddress MACAddress; public DateTime LastSeen; } // 监控参数 private readonly int _detectionInterval = 2000; // 检测间隔(毫秒) private readonly int _gigeVisionPort = 3956; // GigE Vision标准端口 private CancellationTokenSource _cts; private CameraInfo _lastKnownCameraInfo; private CameraStatus _lastStatus = CameraStatus.Disconnected; private readonly string _targetModelPrefix = "TUCAM-API-GenICam"; private readonly byte[] _gigeVisionDiscoveryPacket = new byte[] { 0x00, 0x00, 0x00, 0x01 }; // 开始监控 public void StartMonitoring() { if (_cts != null && !_cts.IsCancellationRequested) return; _cts = new CancellationTokenSource(); Task.Run(() => MonitorLoop(_cts.Token), _cts.Token); } // 停止监控 public void StopMonitoring() { _cts?.Cancel(); } // 主监控循环 private async Task MonitorLoop(CancellationToken token) { while (!token.IsCancellationRequested) { try { CameraInfo? detectedCamera = await DetectCameraAsync(); CameraStatus newStatus = detectedCamera.HasValue ? (IsCameraStreaming(detectedCamera.Value) ? CameraStatus.Streaming : CameraStatus.Connected) : CameraStatus.Disconnected; // 状态变化检测 if (newStatus != _lastStatus || (detectedCamera.HasValue && !detectedCamera.Value.Equals(_lastKnownCameraInfo))) { _lastStatus = newStatus; if (detectedCamera.HasValue) { _lastKnownCameraInfo = detectedCamera.Value; OnStatusChanged?.Invoke(newStatus, _lastKnownCameraInfo); } else { OnStatusChanged?.Invoke(newStatus, default); } } } catch (Exception ex) { Debug.WriteLine($"Monitoring error: {ex.Message}"); OnStatusChanged?.Invoke(CameraStatus.Error, default); } // 等待下一个检测周期 await Task.Delay(_detectionInterval, token); } } // 检测相机是否存在 private async Task<CameraInfo?> DetectCameraAsync() { try { // 步骤1: 获取本地网络接口信息 var localNics = NetworkInterface.GetAllNetworkInterfaces() .Where(n => n.OperationalStatus == OperationalStatus.Up && n.NetworkInterfaceType != NetworkInterfaceType.Loopback) .ToList(); if (localNics.Count == 0) return null; // 步骤2: 扫描所有网络接口上的设备 foreach (var nic in localNics) { var arpResults = await GetArpTableAsync(nic.GetIPProperties().GatewayAddresses.FirstOrDefault()?.Address); foreach (var device in arpResults) { // 步骤3: 检查是否是目标相机 if (await IsTargetCamera(device, nic)) { return new CameraInfo { CameraModel = $"{_targetModelPrefix}[{device.MAC}]", CameraSerial = device.MAC.ToString(), IPAddress = device.IP, MACAddress = device.MAC, LastSeen = DateTime.Now }; } } } } catch { // 忽略扫描错误 } return null; } // 检查是否为目标相机 private async Task<bool> IsTargetCamera(ArpDevice device, NetworkInterface nic) { try { // 方法1: 发送GigE Vision发现包检查响应 using (var udpClient = new UdpClient(new IPEndPoint(nic.GetIPProperties().UnicastAddresses .FirstOrDefault(ip => ip.Address.AddressFamily == AddressFamily.InterNetwork)?.Address, 0))) { udpClient.Client.ReceiveTimeout = 500; udpClient.Connect(new IPEndPoint(device.IP, _gigeVisionPort)); await udpClient.SendAsync(_gigeVisionDiscoveryPacket, _gigeVisionDiscoveryPacket.Length); // 等待响应 var receiveTask = udpClient.ReceiveAsync(); if (await Task.WhenAny(receiveTask, Task.Delay(300)) == receiveTask) { var result = receiveTask.Result; if (result.Buffer.Length > 0) { // 检查响应是否符合GigE Vision标准 return result.Buffer.Length >= 20 && // 最小GVCP包长度 result.Buffer[0] == 0x00 && // 标志位 result.Buffer[1] == 0x00; } } } } catch { // UDP通信失败,尝试备用检测方法 } // 方法2: 检查端口开放情况(备用方法) using (var tcpClient = new TcpClient()) { try { var connectTask = tcpClient.ConnectAsync(device.IP, _gigeVisionPort); if (await Task.WhenAny(connectTask, Task.Delay(300)) == connectTask && tcpClient.Connected) { return true; } } catch { // TCP连接失败 } } return false; } // 检查相机是否在流传输状态 private bool IsCameraStreaming(CameraInfo camera) { try { // 监控流端口(通常为49152-65535范围) var ipProperties = IPGlobalProperties.GetIPGlobalProperties(); var connections = ipProperties.GetActiveTcpConnections(); return connections.Any(c => c.RemoteEndPoint.Address.Equals(camera.IPAddress) && c.RemoteEndPoint.Port >= 49152 && c.State == TcpState.Established); } catch { return false; } } #region ARP扫描实现 // ARP设备结构 private struct ArpDevice { public IPAddress IP; public PhysicalAddress MAC; } // 获取ARP表 private async Task<List<ArpDevice>> GetArpTableAsync(IPAddress gateway) { if (gateway == null) return new List<ArpDevice>(); var devices = new List<ArpDevice>(); var baseIp = gateway.ToString().Substring(0, gateway.ToString().LastIndexOf('.') + 1); // 并行扫描子网 var scanTasks = new List<Task>(); for (int i = 1; i < 255; i++) { var ip = IPAddress.Parse($"{baseIp}{i}"); scanTasks.Add(ScanIpAddress(ip, devices)); } await Task.WhenAll(scanTasks); return devices; } // 扫描单个IP地址 private async Task ScanIpAddress(IPAddress ip, List<ArpDevice> devices) { try { var ping = new Ping(); var reply = await ping.SendPingAsync(ip, 150); if (reply.Status == IPStatus.Success) { var mac = await GetMacAddressAsync(ip); if (mac != PhysicalAddress.None) { lock (devices) { devices.Add(new ArpDevice { IP = ip, MAC = mac }); } } } } catch { // 忽略扫描错误 } } // 获取MAC地址 private async Task<PhysicalAddress> GetMacAddressAsync(IPAddress ip) { try { return await Task.Run(() => { var macAddr = PhysicalAddress.None; int bufferLength = 6; byte[] macBuffer = new byte[bufferLength]; uint destIp = BitConverter.ToUInt32(ip.GetAddressBytes(), 0); if (SendARP(destIp, 0, macBuffer, ref bufferLength) == 0) { macAddr = new PhysicalAddress(macBuffer.Take(bufferLength).ToArray()); } return macAddr; }); } catch { return PhysicalAddress.None; } } // Win32 API声明 [DllImport("iphlpapi.dll", ExactSpelling = true)] private static extern int SendARP(uint destIp, uint srcIp, byte[] macAddress, ref int macAddressLength); #endregion } // 使用示例 public class Program { public static void Main() { Console.WriteLine("TUCAM-API-GenICam Camera Monitor"); var monitor = new GenICamCameraMonitor(); monitor.OnStatusChanged += (status, info) => { string statusText; switch (status) { case GenICamCameraMonitor.CameraStatus.Connected: statusText = "CONNECTED"; break; case GenICamCameraMonitor.CameraStatus.Streaming: statusText = "STREAMING"; break; case GenICamCameraMonitor.CameraStatus.Disconnected: statusText = "DISCONNECTED"; break; default: statusText = "ERROR"; break; } if (status != GenICamCameraMonitor.CameraStatus.Disconnected) { Console.WriteLine($"[{DateTime.Now:HH:mm:ss.fff}] Status: {statusText}"); Console.WriteLine($" Model: {info.CameraModel}"); Console.WriteLine($" Serial: {info.CameraSerial}"); Console.WriteLine($" IP: {info.IPAddress}"); Console.WriteLine($" MAC: {info.MACAddress}"); } else { Console.WriteLine($"[{DateTime.Now:HH:mm:ss.fff}] Camera disconnected"); } }; monitor.StartMonitoring(); Console.WriteLine("Monitoring started. Press any key to exit..."); Console.Read(); /*monitor.StopMonitoring(); Console.WriteLine("Monitoring stopped.");*/ } } 以上代码应该创建C#哪种类型的程序?
10-12
<think>我们分析代码结构:代码中使用了Console.WriteLine,并且最后通过Console.Read等待按键退出。此外,代码中使用了异步任务(Task)和网络操作(UdpClient, TcpClient, Ping等),这些在控制台应用程序中都是常见的。 但是,请注意:代码中使用了Win32 API SendARP(通过DllImport引入),这通常只能在Windows平台上运行。另外,整个程序是一个持续运行(直到按键退出)的监控程序。 因此,这是一个控制台应用程序(Console Application)。它启动后会在控制台输出信息,并持续监控相机状态,直到用户按键退出。 创建项目类型:C# Console Application (.NET Framework 或 .NET Core,但注意跨平台限制) 注意:由于使用了DllImport("iphlpapi.dll"),这个程序只能在Windows上运行。如果要在非Windows平台运行,需要替换ARP获取MAC地址的方式(例如使用系统命令解析)。 所以,应该创建一个C#控制台应用程序项目。 但是,我们也要注意代码中使用了异步的Main方法吗?在C# 7.1及以上版本支持异步Main,但示例中的Main方法并没有标记为async,而是通过monitor.StartMonitoring();启动了一个后台任务。所以,即使Main方法不是异步的,程序也能正常运行(因为监控循环运行在后台线程)。 总结:这是一个控制台应用程序(Console Application),目标框架可以是.NET Framework(例如4.5以上)或.NET Core(需要支持Windows,因为用到了平台调用的SendARP)。 相关问题: 1. 如何修改代码使其在非Windows平台运行? 2. 这段代码中监控循环是如何实现的? 3. 如何优化ARP扫描以提高速度? 4. 在相机状态检测中,为什么使用了UDP和TCP两种方式? </think>根据提供的代码,这是一个 **C# 控制台应用程序(Console Application)**。以下是详细分析: ### 关键特征: 1. **程序入口**:包含 `public static void Main()` 入口方法,这是控制台应用的典型特征 2. **输出方式**:使用 `Console.WriteLine()` 输出信息到命令行窗口 3. **交互方式**:通过 `Console.Read()` 等待用户按键退出 4. **运行模式**:后台监控循环 + 前台命令行交互的混合模式 5. **依赖项**:使用了 `System.Net` 网络库和平台调用(P/Invoke) ### 代码结构说明: ```csharp public class Program { public static void Main() // 控制台应用标准入口 { Console.WriteLine("TUCAM-API-GenICam Camera Monitor"); var monitor = new GenICamCameraMonitor(); // 注册相机状态变化事件 monitor.OnStatusChanged += (status, info) => { ... }; monitor.StartMonitoring(); // 启动后台监控 Console.WriteLine("Monitoring started. Press any key to exit..."); Console.Read(); // 阻塞等待用户输入 } } ``` ### 运行机制: 1. 启动后持续扫描网络中的 GenICam 相机设备 2. 通过 ARP 扫描和端口检测(GigE Vision 3956 端口)识别相机 3. 实时监控相机状态变化(断开/连接/推流) 4. 在控制台实时输出相机状态信息 5. 按任意键退出程序 ### 平台限制: - 依赖 Windows API `SendARP`(iphlpapi.dll) - 需在 **Windows 环境**下运行 - 适合 .NET Framework 4.x 或 .NET Core 3.1+(Windows 版本) ### 编译运行要求: 1. 创建 **Console App 项目**模板 2. 目标框架:.NET Framework 4.7.2+ 或 .NET 6/8(Windows) 3. 需要管理员权限(因涉及原始套接字操作) ### 典型应用场景: - 工业相机设备监控后台服务 - 机器视觉系统设备管理组件 - 自动化测试平台的相机状态检测模块 --- ### 改进建议: 1. **跨平台支持**:替换 `SendARP` 为跨平台的 ARP 实现 2. **日志系统**:集成 Serilog/NLog 替代 `Debug.WriteLine` 3. **配置化**:将端口号、IP 范围等参数改为可配置项 4. **服务化**:可改写成 Windows Service 或 Linux Daemon
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值