SQL
захдаём базу для сквида
потом подрубьаемся
mysql -u ЮЗЕР -pПАРОЛЬ -D БАЗА
скрипт для создания нужных баз (squid.sql)
CREATE TABLE auth (
username char(12) default NULL,
password char(30) default NULL,
admin char(1) NOT NULL default 'N',
maxdaily bigint(15) NOT NULL default '0',
maxweekly bigint(15) NOT NULL default '0',
maxmonthly bigint(15) NOT NULL default '0',
UNIQUE KEY username (username)
) TYPE=MyISAM;
CREATE TABLE logger (
date date default NULL,
time time default NULL,
elapsed decimal(10,0) default NULL,
bill double default NULL,
code tinyint(3) unsigned NOT NULL default '0',
status decimal(3,0) default NULL,
bytes double default NULL,
url char(255) default NULL,
userident char(15) default NULL,
host char(15) default NULL
) TYPE=MyISAM;
CREATE TABLE rdnload (
userident char(12) default NULL,
date date default NULL,
download bigint(15) NOT NULL default '0'
) TYPE=MyISAM;
CREATE TABLE usernames (
username char(12) NOT NULL default '',
realname char(30) default NULL,
title char(30) NOT NULL default '',
department char(30) NOT NULL default '',
phone char(8) NOT NULL default '',
email char(30) NOT NULL default '',
datereg date NOT NULL default '2002-01-01'
) TYPE=MyISAM;
теперь застпавим сквид писать логи через pipe канал сразу в базу
Вместо текстового файла будет находится
pipe-канал. Ничегонеподозревающий Squid будет писать логи о юзерах в
один конец трубы, а perl-скрипт squidsql считывать из другого конца
трубы, разбирать и заносить в базу данных MySQL. Если MySQL будет не
доступен, то информация временно будет записана в файл
/var/log/squid/backup.log
mkfifo /путь/к/логам сквида/access.log
сам скрипт который заносит всё в базу
#!/usr/bin/perl
$mysqluser="user"; # MySQL user name
$mysqlpass="pass"; # MySQL user password
$mysqlserv="localhost"; # MySQL server
$mysqlport="3306"; # MySQL server port
$mysqldbas="база"; # MySQL database name
$mysqltabl="logger"; # MySQL database table
$backuplog="/var/log/squid/backup.log"; # Backup log if couldnt connect to MySQL
# billing setup
$valuepermeg=4; # four roubles per meg
$valueperhour=0; # none per hour, leased line +2880p
# billing method
# 0 for user accounting, 1 for hosts accounting
$usehosts=0
use DBI;
use DBI::DBD;
$dbh=DBI->connect("DBI:mysql:database=$mysqldbas;host=$mysqlserv;port=$mysqlport",$mysqluser,$mysqlpass,{AutoCommit=>1,PrintError=>1})||&errorcon;
$sth=$dbh->prepare("INSERT INTO logger(date,time,elapsed,bill,code,\
status,bytes,url,userident,host)\
VALUES(?,?,?,?,?,?,?,?,?,?)");
open(FBLOGRET,$backuplog);
close(FBLOGRET);
while(<>) {
#
# 0 timestamp.millisec
# 1 duration
# 2 remotehost
# 3 code/status
# 4 bytes
# 5 method
# 6 URL
# 7 username
# 8 peerstatus/peerhost
# 9 type
#
#
chop; # here we now get a string!
# splitting string onto subdata
@lines=split(' ');
# timestamp
$lines[0]=~tr/./ /;
@_timestamp=split(' ',$lines[0]);
$cts=$_timestamp[0];
# date=
($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = gmtime($cts);
$year=$year+1900;
$mon=$mon+1;
$hour=$hour+7;
if ($hour>24) {
$hour=$hour-24;
$mday=$mday+1;
}
$cdate="$year-$mon-$mday";
# time=
$ctime="$hour:$min:$sec";
# elapsed=
$duration=$lines[1];
# host=
$remotehost=$lines[2];
@codestatus=split('/',$lines[3]);
if ($codestatus[0] eq "TCP_HIT") { $_code=0; }
if ($codestatus[0] eq "TCP_MISS") { $_code=1; }
if ($codestatus[0] eq "TCP_REFRESH_HIT") { $_code=2; }
if ($codestatus[0] eq "TCP_REF_FAIL_HIT") { $_code=3; }
if ($codestatus[0] eq "TCP_REFRESH_MISS") { $_code=4; }
if ($codestatus[0] eq "TCP_CLIENT_REFRESH_MISS") { $_code=5; }
if ($codestatus[0] eq "TCP_IMS_HIT") { $_code=6; }
if ($codestatus[0] eq "TCP_SWAPFILE_MISS") { $_code=7; }
if ($codestatus[0] eq "TCP_NEGATIVE_HIT") { $_code=8; }
if ($codestatus[0] eq "TCP_MEM_HIT") { $_code=9; }
if ($codestatus[0] eq "TCP_DENIED") { $_code=10; }
if ($codestatus[0] eq "TCP_OFFLINE_HIT") { $_code=11; }
if ($codestatus[0] eq "UDP_HIT") { $_code=12; }
if ($codestatus[0] eq "UDP_MISS") { $_code=13; }
if ($codestatus[0] eq "UDP_DENIED") { $_code=14; }
if ($codestatus[0] eq "UDP_INVALID") { $_code=15; }
if ($codestatus[0] eq "UDP_MISS_NOFETCH") { $_code=16; }
if ($codestatus[0] eq "NONE") { $_code=17; }
# status=
$_status=$codestatus[1];
# bytes=
$objectsize=$lines[4];
# bill=
$bill=(($duration/60000)*($valueperhour/60))+(($objectsize/1048576)*$valuepermeg);
# method=
$fetchmethod=$lines[5];
#
$URLlink=$lines[6];
$username=$lines[7];
@peerstatus_host=split('/',$lines[8]);
$peerstatus=$peerstatus_host[0];
$peerhost=$peerstatus_host[1];
$objecttype=$lines[9];
############################################################
##
## transfer data to mysql table
##
############################################################
if (($_code ne "10")&&($username ne "-")&&($_status ne "404")&&($_status ne "400")) {
$sth->execute($cdate,
$ctime,
$duration,
$bill,
$_code,
$_status,
$objectsize,
$URLlink,
$username,
$remotehost) || die "cannot transfer data";
$aff="SELECT * FROM rdnload WHERE userident='$username' AND date='$cdate'";
$rows_affected=$dbh->do($aff);
if ($rows_affected < 1) {
$stn=$dbh->prepare("INSERT INTO rdnload(userident,date,download) VALUES (?,?,?)");
$stn->execute($username,$cdate,$objectsize);
}
$aff="UPDATE rdnload SET download=download+$objectsize WHERE userident='$username' AND date='$cdate'";
$rows_affected=$dbh->do($aff);
}
}
$dbh->disconnect;
exit 1;
sub errorconn {
while(<>) {
open(FBLOG,">>".$backuplog);
print FBLOG $_;
close(FBLOG);
}
die "cannot log to MySQL -- data buffered";
}
для запуска сквида рекомендую сделать скриптик /etc/rc.d/rc.squid
следующего соджержания
#!/bin/sh
case "$1" in
start)
/usr/local/squid/sbin/squid2mysql < /var/log/squid/access.log &
# Читаем логи Squid через pipe-канал
/usr/local/squid/sbin/squid # запускаем Squid
echo "Squid starting" # информируем
;;
stop)
/usr/local/squid/sbin/squid -k shutdown # останавливаем Squid
echo "Squid stoping" # информируем
;;
*)
/usr/local/squid/sbin/squid -k reconfigure # рестартуем Squid
echo "Squid restarting" # информируем
;;
esac
exit 0