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
内容概要:本文详细介绍了一种基于Simulink的表贴式永磁同步电机(SPMSM)有限控制集模型预测电流控制(FCS-MPCC)仿真系统。通过构建PMSM数学模型、坐标变换、MPC控制器、SVPWM调制等模块,实现了对电机定子电流的高精度跟踪控制,具备快速动态响应和低稳态误差的特点。文中提供了完整的仿真建模步骤、关键参数设置、核心MATLAB函数代码及仿真结果分析,涵盖转速、电流、转矩和三相电流波形,验证了MPC控制策略在动态性能、稳态精度和抗负载扰动方面的优越性,并提出了参数自整定、加权代价函数、模型预测转矩控制和弱磁扩速等优化方向。; 适合人群:自动化、电气工程及其相关专业本科生、研究生,以及从事电机控制算法研究与仿真的工程技术人员;具备一定的电机原理、自动控制理论和Simulink仿真基础者更佳; 使用场景及目标:①用于永磁同步电机模型预测控制的教学演示、课程设计或毕业设计项目;②作为电机先进控制算法(如MPC、MPTC)的仿真验证平台;③支撑科研中对控制性能优化(如动态响应、抗干扰能力)的研究需求; 阅读建议:建议读者结合Simulink环境动手搭建模型,深入理解各模块间的信号流向与控制逻辑,重点掌握预测模型构建、代价函数设计与开关状态选择机制,并可通过修改电机参数或控制策略进行拓展实验,以增强实践与创新能力。
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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值