需求

1. 将内存、线程数等信息注册到zk上进行监控

2. 统计信息,为下一步做负载均衡做准备。

实现

本文只解决问题1。

从网上查询了下,这些信息可以从proc文件系统中获取,如果不知道proc的,可以Google下。

网上有读取proc信息的lib——libproc,即 procps, 据说htop等实现就是基于它的。

我下载下来了,include和lib都生成了,好不容易找到一篇教程,结果在

stackoverflow上,见有人说有内存泄露,需要如下方法做。

int main(int argc, char** argv)
{
// fillarg used for cmdline
// fillstat used for cmd
PROCTAB* proc = openproc(PROC_FILLARG | PROC_FILLSTAT); while (proc_t* proc_info = readproc(proc, NULL)) {
// do something
freeproc(proc_info)
}
closeproc(proc);
}

于是看proc_t的定义,充满了上世纪的风格,似乎迷失在信息各种信息中了,于是无奈放弃了,直接手撸吧。代码稍后附上,如下是几个关键的技术点

1. 即然shell 命名可以获取proc信息,在C中,我们可以通过popen建立管道,获取shell命令的输出。

2. 获取进程号,可以通过 getpid()

3. sizeof(xx)/sizeof(xx[0]) 可以获取数组的大小。

4. 设计了ZeroHelper 结构,方便了扩展

5. offsetof 宏用于获取元素的偏移

6. 函数指针的应用恰到好处。

#include <time.h>
#include <stddef.h>
#include <string.h>
#include <stdint.h>
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include<unistd.h>
struct StatInfo
{
time_t start_time;
uint32_t duration_sec;
uint32_t conn_cnt;
uint32_t pmem_mb; // peak virtual memory
uint32_t vmem_mb; // virtual memory
uint32_t rmem_mb; // real memory
uint32_t thread_cnt;// 线程数
uint32_t cpu_usage; // cpu
};
typedef int (*convert_fn)(const char* str, void* value_ptr);
struct ZeroHelper {
const char* key;
uint32_t key_len;
uint32_t value_offset;
convert_fn fn;
}; int proc_stat_mem_convert(const char* str, void* value_ptr)
{
uint32_t* value = (uint32_t*)value_ptr;
while (*str && isspace(*str))
++str;
*value = atoi(str);
return ;
}
static const ZeroHelper proc_mem_convert_array[] = {
{"VmPeak:", sizeof("VmPeak:") - , offsetof(StatInfo, pmem_mb), proc_stat_mem_convert},
{"VmSize:", sizeof("VmSize:") - , offsetof(StatInfo, vmem_mb), proc_stat_mem_convert},
{"VmRSS:", sizeof("VmRSS:") - , offsetof(StatInfo, rmem_mb), proc_stat_mem_convert},
{"Threads:", sizeof("Threads:") - , offsetof(StatInfo, thread_cnt), proc_stat_mem_convert},
};
int fresh_memstat_info(pid_t pid, StatInfo* info)
{
char proc_cmd [];
snprintf(proc_cmd, sizeof(proc_cmd), "cat /proc/%d/status", pid);
FILE* fp = popen(proc_cmd, "r");
char proc_line[];
const ZeroHelper* helper = &(proc_mem_convert_array[]);
const int kHelperLen = sizeof(proc_mem_convert_array)/sizeof(proc_mem_convert_array[]);
int j = ;
while (fgets(proc_line, sizeof(proc_line), fp) != NULL)
{
if (j >= kHelperLen)
{
break;
}
// 忽略 key 头部
if (strncmp(proc_line,
helper->key, helper->key_len) == )
{
helper->fn(proc_line + helper->key_len,
(char*)info + helper->value_offset);
++helper;
++j;
}
}
pclose(fp);
return ;
}
int main()
{
StatInfo info;
pid_t pid = getpid();
fresh_memstat_info(pid, &info);
printf("%d\t%ukB\t%ukB\t%ukB\t%u\n",
pid,
info.pmem_mb, info.vmem_mb,
info.rmem_mb, info.thread_cnt);
sleep();
return ;
}

读取proc信息的可扩展实现的更多相关文章

  1. 给虚拟机添加新硬盘并分区,fdisk查看分区,分区,重新读取分区表信息partprobe,格式化,挂载,查看分区挂载信息,自动挂载文件/etc/fstab,/etc/fstab文件错误导致重启崩溃后的修复

    1.虚拟机关机断电 2.添加硬盘 2.开机 3.fdisk -l查看刚才新添加的硬盘 [root@localhost ~]# fdisk -l 磁盘 /dev/sda:21.5 GB, 2147483 ...

  2. ASP.NET Core的配置(1):读取配置信息

    提到"配置"二字,我想绝大部分.NET开发人员脑海中会立马浮现出两个特殊文件的身影,那就是我们再熟悉不过的app.config和web.config,多年以来我们已经习惯了将结构化 ...

  3. 如果正确读取SQL Server中的扩展事件?

        SQL Server中使用扩展事件捕捉所需的信息后,可以选择存放的位置.比如说内存或文件中,但无论存在哪里,其本质都是一个大XML.因此在SQL Server中读取该XML就是解析扩展事件结果 ...

  4. 解惑:NFC手机如何轻松读取银行卡信息?

    自支付宝钱包8.0推出了NFC新功能,只要将支持NFC功能的手机靠近公交卡.银行卡等带有芯片的IC卡上,可迅速读取卡内余额.卡的信息,还可以给卡进行充值,非常贴心实用. 但是很多网友表示担忧,要是别人 ...

  5. 解惑:NFC手机怎样轻松读取银行卡信息?

    自支付宝钱包8.0推出了NFC新功能,仅仅要将支持NFC功能的手机靠近公交卡.银行卡等带有芯片的IC卡上,可迅速读取卡内剩余金额.卡的信息,还能够给卡进行充值,很贴心有用. 可是非常多网友表示担忧,要 ...

  6. DOS下读取spd信息的汇编程序(通过SMBus)

    汇编程序编写的读取spd信息的代码: ;----------------------------------------------------------- ;功能: 通过SMbus 读取内存的SP ...

  7. js读取cookie信息

    1. 第一种方式读取cookie信息:用document.cookie.split(“; “)的方式把字符串分割成几个段,然后遍历整个数组 //javascript方法 function getCoo ...

  8. CEF与JavaScript交互读取电脑信息

    CefSharp中c#和JavaScript交互读取电脑信息 介绍 CEF是由Marshall Greenblatt于2008年创建的基于Google Chromium的BSD许可开源项目.与主要关注 ...

  9. EWS API 2.0读取日历信息-读取内容注意事项

    采用模拟账号的方式读取日历信息,注意下日历的内容读取(Body)读取.代码如下:(采用 EWS API 2.0版本) 1.读取内容前必须设置如下属性:否则会提示:You must load or as ...

随机推荐

  1. HDU 1907 (博弈) John

    参见上一篇博客,里面有分析和结论. #include <cstdio> int main() { int T; scanf("%d", &T); while(T ...

  2. UVa 11988 (数组模拟链表) Broken Keyboard (a.k.a. Beiju Text)

    题意: 模拟一个文本编辑器,可以输入字母数字下划线,如果遇到'['则认为是Home键,如果是']'则认作End键. 问最终屏幕上显示的结果是什么字符串. 分析: 如果在数组用大量的移动字符必然很耗时. ...

  3. 浅谈网络爬虫爬js动态加载网页(二)

    没错,最后我还是使用了Selenium,去实现上一篇我所说的问题,别的没有试,只试了一下firefox的引擎,总体效果对我来说还是可以接受的. 继续昨天的话题,既然要实现上篇所说的问题,那么就需要一个 ...

  4. 手机GUI自动化测试介绍

    手机GUI自动化测试介绍 Posted on 2013/05/15 Xing Binbin(测试工程师) 摘要 众所周知,自动化测试可以一定程度上减轻测试人员负担,提高测试效率,并且通过自动化还可以实 ...

  5. Notepad 列编辑、正则查找、替换

    目标: 将源数据转成初始化sql语句.源数据: 104110040018,1,中国银行,中国银行天津琼州道支行,NULL,1100,天津市,12,天津市 104110040059,1,中国银行,中国银 ...

  6. 【转】不可变数组NSArray与可变数组NSMutableArray

    原文网址:http://www.jianshu.com/p/1ad327f56d1d 不可变数组NSArray //创建一个空数组 NSArray *array = [NSArray array]; ...

  7. 在centOS中加入本地ISO yum源

    注:本文转载自<liujun_live的博客>,感谢原博主的辛勤写作:原文地址:http://blog.sina.com.cn/s/blog_8ea8e9d50101em6f.html 在 ...

  8. 深入理解JavaScript闭包(closure)

    最近在网上查阅了不少javascript闭包(closure)相关的资料,写的大多是非常的学术和专业.对于初学者来说别说理解闭包了,就连文字叙述都很难看懂.撰写此文的目的就是用最通俗的文字揭开Java ...

  9. 【转】为drupal初学者准备的12个精品课程

    下面是一些网上免费的drupal教程,这些教程将对初学者和那些从别的CMS转向drupal的开发者非常有帮助.初级教程 1.在开始用drupal之前,你要知道一些基本的东西,内容很简单,但有些还是值得 ...

  10. 一些JS周边工具

    Visual Studio JS 辅助插件 JScript Editor Extensions 功能: 1.     代码块折叠 2.     方法参数智能提示 3.     代码块Outlining ...