2 * Copyright (c) 2004 Teodor Sigaev <teodor@sigaev.ru>
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. Neither the name of the author nor the names of any co-contributors
14 * may be used to endorse or promote products derived from this software
15 * without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED BY CONTRIBUTORS ``AS IS'' AND ANY EXPRESS
18 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL CONTRIBUTORS BE LIABLE FOR ANY
21 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
23 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
25 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
26 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
27 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37 #include <sys/sysctl.h>
41 #include "connection.h"
48 getsysctl(char *name, void *ptr, size_t len) {
50 if (sysctlbyname(name, ptr, &nlen, NULL, 0) == -1) {
51 tlog(TL_ALARM, "sysctl(\"%s\", ...) failed: %s\n", name,
56 tlog(TL_ALARM, "sysctl(\"%s\", ...) expected %lu, got %lu\n", name,
57 (unsigned long)len, (unsigned long)nlen);
64 #define GETSYSCTL(name, var) getsysctl(name, &(var), sizeof(var))
67 getmeminfo(TCMsgTop *m) {
71 if ( GETSYSCTL("vm.stats.vm.v_inactive_count", memory_tmp) == 0 )
72 m->freemem += memory_tmp;
76 if ( m->freemem>=0 && GETSYSCTL("vm.stats.vm.v_free_count", memory_tmp) == 0 )
77 m->freemem += memory_tmp;
82 m->freemem *= getpagesize();
84 if ( GETSYSCTL("hw.physmem", memory_tmp1) == 0 )
85 m->physmem = memory_tmp1;
89 #elif defined Linux /* end FreeBSD */
91 #define MEMBUFSIZE 256
94 * if str mathes by pattern returns poineter to begin of value
95 * and NULL in opposite case
98 cmpPattern( char *str, char *pattern ) {
99 while( *str != '\0' && *str == *pattern ) {
104 if ( *pattern == '\0' ) {
109 * str matches by pattern, so skip leading spaces
110 * before actual value
112 while( *str != '\0' ) {
113 if ( isspace( *str ) )
124 getmeminfo(TCMsgTop *m) {
126 static char buf[MEMBUFSIZE];
129 fh=fopen("/proc/meminfo", "r");
131 tlog(TL_ALARM, "fopen(\"/proc/meminfo\", ...) failed: %s", strerror(errno));
135 while( fgets(buf, MEMBUFSIZE, fh) && (m->physmem == 0 || m->freemem == 0) ) {
136 if ( (ptr = cmpPattern(buf, "MemTotal:")) != NULL ) {
137 m->physmem = atoll(ptr) * 1024; /* mem in Kb */
138 } else if ( (ptr = cmpPattern(buf, "MemFree:")) != NULL ) {
139 m->freemem = atoll(ptr) * 1024; /* mem in Kb */
147 #error No memory stat for current OS
153 fillMsgTop(TCMsgTop *m) {
156 memset(m,0,sizeof(TCMsgTop));
157 if ( getloadavg(lll,3) >= NITEM+1 )
166 tlog( TL_DEBUG, "Sended topdata: %.2f load, %lld free, %lld total", m->load, m->freemem, m->physmem);
172 int msglen = TCMSGHDRSZ + sizeof(TCMsgTop);
175 pmsg = (TCMsg*)tmalloc(msglen);
182 pmsg->type=TOPMSGTYPE;
183 fillMsgTop( (TCMsgTop*)(pmsg->data) );
185 return TC_sendMsg(msg);
190 "Copyright (c) 2004-2007 Teodor Sigaev <teodor@sigaev.ru>. All rights reserved.\n"
191 "sendtop - small daemon to send load of box to server\n"
193 "./sendtop [-D] -h HOST [-p PORT] [-s PERIOD]\n"
194 " -D - debug mode (do not daemonize, print to stderr instead of syslog)\n"
195 " -h HOST - server IP to send data\n"
196 " -p PORT - port number of server\n"
197 " -s PERIOD - period of of send (in seconds)\n",
206 main( int argc, char *argv[] ) {
209 int debug=0, child=0;
212 msg.port = TOPD_SERVER_DEFAULT_PORT;
217 while( (ch=getopt(argc, argv, "h:p:s:D"))!=-1) {
220 msg.host = strdup(optarg);
223 msg.port = atoi(optarg);
226 period = atoi(optarg);
240 signal(SIGCHLD, SIG_IGN);
243 opentlog( TL_OPEN_STDERR, TL_DEBUG, NULL);
245 opentlog( TL_OPEN_SYSLOG, TL_INFO, NULL);
247 if ( debug || (child = fork()) == 0 ) {
256 tlog(TL_CRIT|TL_EXIT, "Can't start child process: %s", strerror(errno));