Поиск на сайте: Расширенный поиск


Новые программы oszone.net Читать ленту новостей RSS
CheckBootSpeed - это диагностический пакет на основе скриптов PowerShell, создающий отчет о скорости загрузки Windows 7 ...
Вы когда-нибудь хотели создать установочный диск Windows, который бы автоматически установил систему, не задавая вопросо...
Если после установки Windows XP у вас перестала загружаться Windows Vista или Windows 7, вам необходимо восстановить заг...
Программа подготовки документов и ведения учетных и отчетных данных по командировкам. Используются формы, утвержденные п...
Red Button – это мощная утилита для оптимизации и очистки всех актуальных клиентских версий операционной системы Windows...
OSzone.net Видео Unix Интернет Apache Пример apache модуля для подсчета трафика RSS

Пример apache модуля для подсчета трафика

Текущий рейтинг: 5 (проголосовало 2)
 Посетителей: 914 | Просмотров: 1171 (сегодня 0)  Шрифт: - +
  Встал тут вопрос подсчета апачевского трафика. После изучения
  вопроса было найдено два модуля - 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 */


Иcточник: http://www.opennet.ru  •  Опубликована: 05.03.2005
Нашли ошибку в тексте? Сообщите о ней автору: выделите мышкой и нажмите CTRL + ENTER
Теги:  


Оценить статью:
Вверх
Комментарии посетителей
Комментарии отключены. С вопросами по статьям обращайтесь в форум.