diff --git a/openbsd/common.h b/openbsd/common.h new file mode 100644 index 0000000..5904c16 --- /dev/null +++ b/openbsd/common.h @@ -0,0 +1,43 @@ +/* + * Copyright 2012 Matthew McCormick + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * */ +// This file was Authored by Justin Crawford +// Based on: github.com/freebsd/freebsd/blob/master/usr.bin/top/machine.c +// Based on: Apple.cpp for load_string/mem_string and apple's documentation + +#ifndef BSD_METER_COMMON_H_ +#define BSD_METER_COMMON_H_ + +#include + +// Memory Sizes +#define KILOBYTES(x) ((x)/1024) +#define MEGABYTES(x) (KILOBYTES((x))/1024) +#define GIGABYTES(x) (MEGABYTES((x))/1024) + +// CPU percentages stuff +#define CP_USER 0 +#define CP_NICE 1 +#define CP_SYS 2 +#define CP_INTR 3 +#define CP_IDLE 4 +#define CPUSTATES 5 + +inline void error(const char * error) { + std::cerr << error << std::endl; + exit(23); +} + +#endif diff --git a/openbsd/cpu.cc b/openbsd/cpu.cc new file mode 100644 index 0000000..fc22f94 --- /dev/null +++ b/openbsd/cpu.cc @@ -0,0 +1,85 @@ +/* + * Copyright 2012 Matthew McCormick + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * */ +// This file was Authored by Justin Crawford +// Based on: github.com/freebsd/freebsd/blob/master/usr.bin/top/machine.c +// Based on: Apple.cpp for load_string/mem_string and apple's documentation + +#include +#include // usleep + +#include +#include + +#include "common.h" +#include "cpu.h" + +uint8_t get_cpu_count() +{ + int cpu_count = 1; // default to 1 + int mib[2] = { CTL_HW, HW_NCPU }; + size_t len = sizeof( cpu_count ); + + if(sysctl(mib, 2, &cpu_count, &len, NULL, 0) < 0) + { + error("sysctl: error getting cpu count"); + } + + return cpu_count; +} + +float cpu_percentage( unsigned int cpu_usage_delay ) +{ + int cpu_ctl[] = { CTL_KERN, KERN_CPTIME }; + + int32_t load1[CPUSTATES]; + int32_t load2[CPUSTATES]; + + size_t size = sizeof( load1 ); + + // get cpu times + if(sysctl(cpu_ctl, 2, &load1, &size, NULL, 0) < 0) + { + error("sysctl: error getting cpu stats"); + } + + usleep(cpu_usage_delay); + + // update cpu times + if(sysctl(cpu_ctl, 2, &load2, &size, NULL, 0) < 0) + { + error("sysctl: error getting cpu stats"); + } + + // Current load times + unsigned long long current_user = load1[CP_USER]; + unsigned long long current_system = load1[CP_SYS]; + unsigned long long current_nice = load1[CP_NICE]; + unsigned long long current_idle = load1[CP_IDLE]; + // Next load times + unsigned long long next_user = load2[CP_USER]; + unsigned long long next_system = load2[CP_SYS]; + unsigned long long next_nice = load2[CP_NICE]; + unsigned long long next_idle = load2[CP_IDLE]; + // Difference between the two + unsigned long long diff_user = next_user - current_user; + unsigned long long diff_system = next_system - current_system; + unsigned long long diff_nice = next_nice - current_nice; + unsigned long long diff_idle = next_idle - current_idle; + + return static_cast(diff_user + diff_system + diff_nice) / + static_cast(diff_user + diff_system + diff_nice + diff_idle) * + 100.0; +} diff --git a/openbsd/cpu.h b/openbsd/cpu.h new file mode 100644 index 0000000..ab8cee9 --- /dev/null +++ b/openbsd/cpu.h @@ -0,0 +1,9 @@ +#ifndef CPU_H_ +#define CPU_H_ + +#include + +float cpu_percentage(unsigned); +uint8_t getCpuCount(); + +#endif diff --git a/openbsd/load.cc b/openbsd/load.cc new file mode 100644 index 0000000..8434400 --- /dev/null +++ b/openbsd/load.cc @@ -0,0 +1,78 @@ +/* + * Copyright 2012 Matthew McCormick + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * */ +// This file was Authored by Justin Crawford +// Based on: https://github.com/freebsd/freebsd/blob/master/usr.bin/top/machine.c +// Based on: Apple.cpp for load_string/mem_string and apple's documentation + + +#include +#include +#include // getloadavg() +#include // floorf() +#include + +#include "cpu.h" +#include "load.h" +#include "../luts.h" + +// Load Averages +std::string load_string( bool use_colors = false ) +{ + std::stringstream ss; + // Only get 3 load averages + cont int nelem = 3; + double averages[nelem]; + // based on: opensource.apple.com/source/Libc/Libc-262/gen/getloadavg.c + + if( getloadavg( averages, nelem ) < 0) + { + ss << "0.00 0.00 0.00"; // couldn't get averages. + } + else + { + if( use_colors ) + { + // may not work + uint8_t cpu_count = getCpuCount(); + + unsigned load_percent = static_cast( + averages[0] / cpu_count * 0.5f * 100.0f); + + if( load_percent > 100 ) + { + load_percent = 100; + } + + ss << load_lut[load_percent]; + } + + for( int i = 0; i < nelem; ++i ) + { + // Round to nearest, make sure this is only a 0.00 value not a 0.0000 + float avg = floorf( static_cast (averages[i] ) * 100 + 0.5 ) / 100; + ss << avg << " "; + } + + if( use_colors ) + { + ss << "#[fg=default,bg=default]"; + } + + } + + return ss.str(); +} + diff --git a/openbsd/load.h b/openbsd/load.h new file mode 100644 index 0000000..3b8d814 --- /dev/null +++ b/openbsd/load.h @@ -0,0 +1,8 @@ +#ifndef LOAD_H_ +#define LOAD_H_ + +#include + +std::string load_string( bool ); + +#endif diff --git a/openbsd/memory.cc b/openbsd/memory.cc new file mode 100644 index 0000000..6442a1d --- /dev/null +++ b/openbsd/memory.cc @@ -0,0 +1,110 @@ +/* + * Copyright 2012 Matthew McCormick + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * */ +// This file was Authored by Justin Crawford +// Pawel Soltys + +//#error ToDo: OpenBSD. This file is incomplete and likely will not compile if +//you remove this error (it is here to tell you it's unfinished) + +#include +#include +#include +#include +#include // vmtotal struct + +#include "common.h" +#include "memory.h" +#include "../luts.h" + +static int pageshift; + +#define pagesh(size) ((size) << pageshift) + +std::string mem_string( bool use_colors = false ) +{ + std::ostringstream oss; + + // These values are in bytes + int64_t total_mem = 0; + int64_t used_mem = 0; + int32_t free_mem = 0; + size_t size; + + // get page size + static int hw_pagesize[] = { CTL_HW, HW_PAGESIZE }; + int page_size = 0; + size = sizeof( page_size ); + if( sysctl( hw_pagesize, 2, &page_size, &size, NULL, 0) < 0) + { + error("memory: error getting page size"); + exit(23); + } + + // calculate how far we must shift the variables + pageshift = 0; + while( page_size > 1 ) + { + pageshift++; + page_size >>= 1; + } + + // get vm memory stats + static int vm_totalmem[] = { CTL_VM, VM_METER }; + struct vmtotal vm_total; + size = sizeof( vm_total ); + if( sysctl( vm_totalmem, 2, &vm_total, &size, NULL, 0 ) < 0 ) + { + error("memory: error getting vm memory stats"); + exit(23); + } + + // In case we need it, this gets the cached memory (bcstats.numbufpages) + static int vm_bcstats[] = { CTL_VFS, VFS_GENERIC, VFS_BCACHESTAT }; + struct bcachestats bcstats; + size = sizeof( bcstats ); + if( sysctl( vm_bcstats, 3, &bcstats, &size, NULL, 0 ) < 0 ) + { + error( "memory: error getting cached memory size" ); + exit( 23 ); + } + + // calculations based on conky openbsd port + used_mem = pagesh( vm_total.t_rm ); + free_mem = pagesh( vm_total.t_free ); + + // from nagios-memory plugin + used_mem -= pagesh( bcstats.numbufpages ); + free_mem += pagesh( bcstats.numbufpages ); + + // calculate total memory + total_mem = used_mem + free_mem; + + if( use_colors ) + { + oss << mem_lut[( 100 * used_mem ) / total_mem]; + } + + oss << convert_unit( used_mem, MEGABYTES ) + << '/' << convert_unit( total_mem, MEGABYTES ) << "MB"; + + if( use_colors ) + { + oss << "#[fg=default,bg=default]"; + } + + return oss.str(); +} + diff --git a/openbsd/memory.h b/openbsd/memory.h new file mode 100644 index 0000000..196dfd6 --- /dev/null +++ b/openbsd/memory.h @@ -0,0 +1,8 @@ +#ifndef MEMORY_H_ +#define MEMORY_H_ + +#include + +std::string mem_string( bool ); + +#endif