The OpenNET Project / Index page

[ новости /+++ | форум | теги | ]

Пример apache модуля для подсчета трафика (apache module traffic log)


<< Предыдущая ИНДЕКС Поиск в статьях src Установить закладку Перейти на закладку Следующая >>
Ключевые слова: apache, module, traffic, log,  (найти похожие документы)
Date: Wed, 27 Oct 2004 12:23:59 +0400 From: Roman Listov <r2l@maker.ru.> Subject: Пример apache модуля для подсчета трафика Прошу прощения, если напрягаю. Встал тут вопрос подсчета апачевского трафика. После изучения вопроса было найдено два модуля - mod_watch от snert.com и mod_accounting. Первый весьма продвинут, но, имхо, тяжеловат и перегружен опциями... и без настроек результатирующего файлва. дело в том, что хотелось бы сохранять еще и зону, с которой получен трафик (и которую выдает мне mod_geo). mod_accounting гораздо попросче, даже я смог приковырять туда сохранение зоны, но... блин, валить все в рилтайме в базу... имхо, полный оверхед. В итоге на основе mod_accounting создал модулек, просто выставляющий переменные окружения для последующего использования их в LogFormat. Но так как программирование на Ц у меня в зачаточном состоянии, был бы благодарен, если бы кто пробежался итог взглядом и указал где я неправ (хоть модуль и работает, но мало ли что). А может и на другие подводные камни такого подсчета. Спасибо! //#define DEBUG #include <stdio.h> #include <stdlib.h> #include "mod_bytess.h" #define MOD_BYTESS_VERSION_INFO_STRING "mod_bytess/0.1" module MODULE_VAR_EXPORT bytess_module; // hook function pass to ap_table_do() static int GetHeaderLen( long *count, const char *key, const char *val ) { *count += strlen( key ) + strlen( val ) + 4; // 4 for ": " + CR + LF #ifdef DEBUG ap_log_error( APLOG_MARK, ERRLEVEL, rr->server, ap_pstrcat( rr->pool, key, ": ", val, NULL )); #endif return( 1 ); } // computes the length of a table static long TableLen( request_rec *r, table *tab ) { long count = 0; if( tab ) ap_table_do((int (*) (void *, const char *, const char *)) GetHeaderLen, (void *) &count, tab, NULL ); return( count ); } // computes the number of bytes sent static long BytesSent( request_rec *r ) { long sent, status_len = 0; char *custom_response; #ifdef DEBUG ap_log_error( APLOG_MARK, ERRLEVEL, rr->server, "BytesSent" ); #endif // let's see if it's a failed redirect // I'm using the same logic of ap_send_error_response() if( custom_response = (char *)ap_response_code_string( r, ap_index_of_response( r->status ))) { // if so, find the original request_rec if( custom_response[0] != '"' ) while( r->prev && ( r->prev->status != HTTP_OK )) r = r->prev; } if( r->status_line ) status_len = strlen( r->status_line ); sent = TableLen( r, r->headers_out ) + TableLen( r, r->err_headers_out ) + 2 + // 2 for CRLF 11 + status_len + // HTTP/1.x nnn blah 10 + strlen( ap_get_server_version() ) + // Server: line 8 + strlen( ap_gm_timestr_822( r->pool, r->request_time )); // Date: line if(( sent >= 255 ) && ( sent <= 257 )) sent += sizeof( "X-Pad: avoid browser bug" ) + 1; if( r->sent_bodyct ) { if( r->connection ) { long int bs; // this is more accurate than bytes_sent in presence of modules // which manipulate the output (eg. mod_gzip) ap_bgetopt( r->connection->client, BO_BYTECT, &bs ); sent += bs; } else sent += r->bytes_sent; } return( sent ); } // computes the number of bytes received static long BytesRecvd( request_rec *r ) { long recvd; const char *len; #ifdef DEBUG ap_log_error( APLOG_MARK, ERRLEVEL, rr->server, "BytesRecvd" ); #endif recvd = strlen( r->the_request ) + TableLen( r, r->headers_in ) + 4; // 2 for CRLF after the request, 2 for CRLF after all headers len = ap_table_get( r->headers_in, "Content-Length" ); if( len ) recvd += atol( len ); return( recvd ); } // typedef const char *(*hook_func)(); // ------------------- HOOKS ----------------- static int acct_transaction( request_rec *orig ) { request_rec *r = orig; // get to the last of the chain, we need the correct byte counters ;-) while( r->next ) r = r->next; ap_table_setn(r->subprocess_env, "BYTES_R", ap_psprintf(r->pool, "%ld", BytesRecvd( orig )) ); ap_table_setn(r->subprocess_env, "BYTES_S", ap_psprintf(r->pool, "%ld", BytesSent( r )) ); return( OK ); } static void mod_acct_init( server_rec *server, pool *p ) { ap_add_version_component(MOD_BYTESS_VERSION_INFO_STRING); } // ------------------- MOD CONFIG ----------------- /* The configuration array that sets up the hooks into the module. */ module bytess_module = { STANDARD_MODULE_STUFF, mod_acct_init, /* initializer */ NULL, /* create per-dir config */ NULL, /* merge per-dir config */ NULL, /* server config */ NULL, /* merge server config */ NULL, /* command table */ NULL, /* handlers */ NULL, /* filename translation */ NULL, /* check_user_id */ NULL, /* check auth */ NULL, /* check access */ NULL, /* type_checker */ NULL, /* fixups */ acct_transaction, /* logger */ #if MODULE_MAGIC_NUMBER >= 19970103 NULL, /* header parser */ #endif #if MODULE_MAGIC_NUMBER >= 19970719 NULL, /* child_init */ #endif #if MODULE_MAGIC_NUMBER >= 19970728 NULL, /* process exit/cleanup */ #endif #if MODULE_MAGIC_NUMBER >= 19970902 NULL /* [#0] post read-request */ #endif }; #ifndef MOD_BYTESS_H #define MOD_BYTESS_H #include <time.h> #include "httpd.h" #include "http_config.h" #include "http_log.h" #include "http_core.h" #define ERRLEVEL (APLOG_ERR|APLOG_NOERRNO) #define DEBUGLEVEL (APLOG_INFO|APLOG_NOERRNO) #endif /* MOD_BYTESS_H */

<< Предыдущая ИНДЕКС Поиск в статьях src Установить закладку Перейти на закладку Следующая >>

Обсуждение [ RSS ]
  • 1, soko1 (??), 10:16, 08/10/2009 [ответить]  
  • +/
    О, а заголовочные файлы можете скинуть сюда: nullbsd гмаил.ком
    Благодарю!
     

     Добавить комментарий
    Имя:
    E-Mail:
    Заголовок:
    Текст:




    Партнёры:
    PostgresPro
    Inferno Solutions
    Hosting by Hoster.ru
    Хостинг:

    Закладки на сайте
    Проследить за страницей
    Created 1996-2024 by Maxim Chirkov
    Добавить, Поддержать, Вебмастеру