Das ist richtig, ich habe diesen PHP-Code schnell umgeschrieben. Ich gebe zu, daß ich nicht weiß, ob es Zeiger bei Strings in PHP gibt.
Eigentlich verwende ich ein kleines C++ - Programm unter Windows, es sollte für Linux aber auch mit kleinen Änderungen funktionieren (vorsicht, CMySQL ist nicht vorbildlicher Programmierstil). Wenn man PHP kann, ist es nicht schwer, den Code zu verstehen. Vielleicht kann es jemand brauchen?
Code: Alles auswählen
// logtomysql.cpp : Definiert den Einsprungpunkt für die Konsolenanwendung.
//
#define WIN32_LEAN_AND_MEAN
#include "stdafx.h"
#include <stdio.h>
#include <windows.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <memory.h>
#include <winsock.h>
#define USE_OLD_FUNCTIONS
#include <mysql.h>
//------------------------------------------------
static char g_query[16384];
//------------------------------------------------
class CMySQL
{
public:
__forceinline my_ulonglong NumRows(MYSQL_RES* pRes);
__forceinline void QueryNoResult(LPCTSTR lpszQuery);
__forceinline unsigned FetchRow0AsUnsigned(MYSQL_RES* res);
CMySQL(LPCSTR lpszServer, LPCSTR lpszUser, LPCSTR lpszPwd, LPCSTR lpszDB);
__forceinline void OnError(unsigned line, LPCSTR g_query);
__forceinline MYSQL_RES* Query(LPCSTR lpszQuery);
__forceinline MYSQL_ROW FetchRow(MYSQL_RES* res);
__forceinline LPSTR FetchRow0(MYSQL_RES* res);
void Close();
__forceinline LPSTR EscapeString(LPSTR string);
__forceinline my_ulonglong InsertID();
__forceinline MYSQL* GetConnectionHandle();
protected:
char buffer[16384];
MYSQL* connection;
MYSQL_RES* g_anyrequest;
};
//------------------------------------------------
__forceinline my_ulonglong CMySQL::NumRows(MYSQL_RES *pRes)
{
return mysql_num_rows(pRes);
}
//------------------------------------------------
__forceinline MYSQL* CMySQL::GetConnectionHandle()
{
return connection;
}
//------------------------------------------------
__forceinline my_ulonglong CMySQL::InsertID()
{
return mysql_insert_id(connection);
}
//------------------------------------------------
__forceinline LPSTR CMySQL::EscapeString(LPSTR string)
{
mysql_real_escape_string(connection, buffer, string, lstrlen(string));
return buffer;
}
//------------------------------------------------
__forceinline void CMySQL::QueryNoResult(LPCTSTR lpszQuery)
{
mysql_query(connection, lpszQuery);
g_anyrequest = mysql_store_result(connection);
if(mysql_errno(connection) > 0)
printf("%s\r\n%s\r\n", mysql_error(connection), g_query);
mysql_free_result(g_anyrequest);
}
//------------------------------------------------
void CMySQL::Close()
{
mysql_close(connection);
}
//------------------------------------------------
__forceinline MYSQL_ROW CMySQL::FetchRow(MYSQL_RES* res)
{
return mysql_fetch_row(res);
}
//------------------------------------------------
__forceinline LPSTR CMySQL::FetchRow0(MYSQL_RES* res)
{
MYSQL_ROW row = mysql_fetch_row(res);
return row[0];
}
//------------------------------------------------
__forceinline unsigned CMySQL::FetchRow0AsUnsigned(MYSQL_RES *res)
{
MYSQL_ROW row = mysql_fetch_row(res);
return (unsigned)atoi(row[0]);
}
//------------------------------------------------
CMySQL::CMySQL(LPCSTR lpszServer, LPCSTR lpszUser, LPCSTR lpszPwd, LPCSTR lpszDB)
{
connection = mysql_init(NULL);
if( !mysql_real_connect(connection, lpszServer, lpszUser, lpszPwd, lpszDB, 0, NULL, 0) )
OnError(0, "mysql_real_connect");
if( mysql_select_db(connection, lpszDB) )
OnError(0, "mysql_select_db");
}
//------------------------------------------------
__forceinline MYSQL_RES* CMySQL::Query(LPCSTR lpszQuery)
{
mysql_query(connection, lpszQuery);
MYSQL_RES* ancc = mysql_store_result(connection);
if(mysql_errno(connection) > 0)
printf("%s\r\n%s\r\n", mysql_error(connection), g_query);
return ancc;
}
//------------------------------------------------
__forceinline void CMySQL::OnError(unsigned line, LPCSTR g_query)
{
if(mysql_errno(connection) > 0)
printf("\r\nZeile %d : %s\r\n%s\r\n", line, mysql_error(connection), g_query);
}
//------------------------------------------------
char buf2[4096];
char values[4096];
char buf3[1024];
char tx1[16];
char tx2[16];
char szLogExtOld[6];
typedef struct tagLOGLINE
{
char ip[32];
char date[32];
char method[32];
char uri[4096];
char code[8];
char size[16];
char host[128];
char referer[4096];
char ua[512];
my_ulonglong uaid;
char via[32];
DWORD dwIP;
} LOGLINE;
static LOGLINE l;
static LPSTR base;
static LPSTR point;
static unsigned d;
//------------------------------------------------
static char szOldUA[512];
static my_ulonglong idOld;
static char szSQLID[1024];
__forceinline my_ulonglong GetUAID(CMySQL* connection, LOGLINE* pLine)
{
if(0 == lstrcmp(pLine->ua, szOldUA))
return idOld;
redo:
my_ulonglong idx = 0;
wsprintf(szSQLID, "SELECT idx FROM ua WHERE HTTP_USER_AGENT='%s';", pLine->ua);
MYSQL_RES* pRes = connection->Query(szSQLID);
if(connection->NumRows(pRes) > 0)
idx = connection->FetchRow0AsUnsigned(pRes);
else
{
wsprintf(szSQLID, "INSERT INTO ua (HTTP_USER_AGENT) VALUES ('%s');", pLine->ua);
connection->QueryNoResult(szSQLID);
printf("+ ");
goto redo;
}
mysql_free_result(pRes);
lstrcpy(szOldUA, pLine->ua);
idOld = idx;
return idx;
}
//------------------------------------------------
__forceinline void ConvertIP(LOGLINE* pLine)
{
BYTE a, b, c, d;
LPSTR base = pLine->ip;
LPSTR lpsz = strchr(base, '.');
ZeroMemory(tx1, sizeof(tx1));
memcpy(tx1, base, lpsz-base);
a = atoi(tx1);
base = lpsz + 1;
lpsz = strchr(base, '.');
ZeroMemory(tx1, sizeof(tx1));
memcpy(tx1, base, lpsz-base);
b = atoi(tx1);
base = lpsz + 1;
lpsz = strchr(base, '.');
ZeroMemory(tx1, sizeof(tx1));
memcpy(tx1, base, lpsz-base);
c = atoi(tx1);
base = lpsz + 1;
d = atoi(base);
pLine->dwIP = d + (c << 8) + (b << 16) + (a << 24);
}
//------------------------------------------------
char szLogExt[6];
__forceinline void DoInserts(CMySQL* connection, LPSTR szLogExt)
{
szLogExt[0] = l.date[2];
szLogExt[1] = l.date[3];
szLogExt[2] = '_';
szLogExt[3] = l.date[5];
szLogExt[4] = l.date[6];
szLogExt[5] = 0;
// ua-id
l.uaid = GetUAID(connection, &l);
_i64toa(l.uaid, tx1, 10);
sprintf(tx2, "%u", l.dwIP);
// tabelle
if(0 != strcmp(szLogExtOld, szLogExt))
{
sprintf(buf2, "CREATE TABLE IF NOT EXISTS `_logs%s` (`idx` int(11) NOT NULL auto_increment, `REMOTE_ADDR` varchar(16) NOT NULL default '',`REMOTE_ADDR_NUM` int(11) default NULL, `TIME` timestamp NOT NULL, `METHOD` varchar(8) NOT NULL default '', `REQUEST_URI` text NOT NULL, `STATUSCODE` int(11) NOT NULL default '0', `SIZE` int(11) default NULL, `HTTP_REFERER` text NOT NULL, `UA_ID` int(11) default NULL, `HTTP_VIA` varchar(16) NOT NULL default '', PRIMARY KEY (`idx`), KEY `ip` (`REMOTE_ADDR`), KEY `ua` (`UA_ID`)) TYPE=MyISAM ;", szLogExt);
connection->Query(buf2);
connection->Query("DROP TABLE logs");
lstrcpy(szLogExtOld, szLogExt);
lstrcpy(buf2, "SHOW TABLES LIKE '\\_logs%%';");
MYSQL_RES* resTables = connection->Query(buf2);
unsigned ky = 0;
unsigned rows_ky = (unsigned)mysql_num_rows(resTables);
// komplette MERGE erstellen
lstrcpy(buf2, "CREATE TABLE IF NOT EXISTS `logs` (`idx` int(11) NOT NULL auto_increment, `REMOTE_ADDR` varchar(16) NOT NULL default '',`REMOTE_ADDR_NUM` int(11) default NULL, `TIME` timestamp NOT NULL, `METHOD` varchar(8) NOT NULL default '', `REQUEST_URI` text NOT NULL, `STATUSCODE` int(11) NOT NULL default '0', `SIZE` int(11) default NULL, `HTTP_REFERER` text NOT NULL, `UA_ID` int(11) default NULL, `HTTP_VIA` varchar(16) NOT NULL default '', PRIMARY KEY (`idx`), KEY `ip` (`REMOTE_ADDR`), KEY `ua` (`UA_ID`)) TYPE=MERGE UNION=(");
while(ky < rows_ky-1)
{
lstrcat(buf2, connection->FetchRow0(resTables));
lstrcat(buf2, ", ");
ky++;
}
lstrcat(buf2, connection->FetchRow0(resTables));
lstrcat(buf2, ");");
connection->Query(buf2);
}
// jetzt SQL
sprintf(buf2, "INSERT INTO _logs%s (REMOTE_ADDR, REQUEST_URI, STATUSCODE, SIZE, HTTP_REFERER, UA_ID, HTTP_VIA, TIME, METHOD, REMOTE_ADDR_NUM) VALUES ('%s', '%s', %s, '%s', '%s', '%s', '%s', '%s', '%s', '%s'); ",
szLogExt, l.ip, l.uri, l.code, l.size, l.referer, tx1, l.via, l.date, l.method, tx2);
connection->Query(buf2);
}
//------------------------------------------------
__forceinline LPSTR ReadLogLine1und1(CMySQL* connection, LPSTR szCurrent)
{
// Log-Format:
// 82.39.117.93 - - [08/Feb/2005:00:09:54 +0100] "GET /test.css HTTP/1.1" 200 2972 www.hostname.net "http://www.hostname.net/foo/bar.htm" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)" "-"
ZeroMemory(&l, sizeof(l));
LPSTR szCurrent2 = strchr(szCurrent, '\n') + 1;
int register len = 0;
// ip
base = szCurrent;
point = strchr(base, ' ');
memcpy(l.ip, base, point-base);
base = point++;
ConvertIP(&l);
// datum
point = strchr(base, ']') + 1;
base = strchr(base, '[') + 1;
ZeroMemory(buf3, sizeof(buf3));
memcpy(buf3, base, point-base);
memcpy(tx1, buf3+3, 3);
tx1[3] = 0;
switch(tx1[0])
{
case 'J' :
if(tx1[1] == 'a')
d = 1;
else if (tx1[2] == 'l')
d = 7;
else d = 6;
break;
case 'F' :
d = 2;
break;
case 'M' :
if(tx1[2] == 'r')
d = 3;
else if (tx1[2] == 'y')
d = 5;
break;
case 'A' :
if(tx1[1] == 'p')
d = 4;
else
d = 8;
break;
case 'S' :
d = 9;
break;
case 'O' :
d = 10;
break;
case 'N' :
d = 11;
break;
case 'D' :
d = 12;
break;
}
sprintf(tx2, "%2.2d", d);
l.date[0] = buf3[7];
l.date[1] = buf3[8];
l.date[2] = buf3[9];
l.date[3] = buf3[10];
l.date[4] = '-';
l.date[5] = tx2[0];
l.date[6] = tx2[1];
l.date[7] = '-';
l.date[8] = buf3[0];
l.date[9] = buf3[1];
l.date[10] = ' ';
l.date[11] = buf3[12];
l.date[12] = buf3[13];
l.date[13] = buf3[14];
l.date[14] = buf3[15];
l.date[15] = buf3[16];
l.date[16] = buf3[17];
l.date[17] = buf3[18];
l.date[18] = buf3[19];
l.date[19] = 0;
// meth
base = point+2;
point = strchr(base, ' ');
memcpy(l.method, base, point-base);
base = point+1;
// uri
point = strchr(base, ' ') ;
ZeroMemory(buf3, sizeof(buf3));
len = point-base;
if(len > 255)
len=255;
memcpy(buf3, base, len);
mysql_real_escape_string(connection->GetConnectionHandle(), l.uri, buf3, lstrlen(buf3));
base = point + 2;
base = strchr(base, ' ') + 1;
// code
point = strchr(base, ' ') ;
memcpy(l.code, base, point-base);
base = ++point;
// groesse
point = strchr(base, ' ') ;
memcpy(l.size, base, point-base);
base = ++point;
// host
point = strchr(base, ' ') ;
memcpy(l.host, base, point-base);
base = point+2;
// ref
point = strchr(base, '\"') ;
ZeroMemory(buf3, sizeof(buf3));
len = point-base;
if(len > 512)
len=512;
memcpy(buf3, base, len);
mysql_real_escape_string(connection->GetConnectionHandle(), l.referer, buf3, lstrlen(buf3));
base = point+3;
// ua
point = strchr(base, '\"') ;
ZeroMemory(buf3, sizeof(buf3));
len = point-base;
if(len > 255)
len=255;
memcpy(buf3, base, len);
mysql_real_escape_string(connection->GetConnectionHandle(), l.ua, buf3, lstrlen(buf3));
base = point+3;
// via
point = strchr(base, '\"') ;
memcpy(l.via, base, point-base);
base = point+2;
// jetzt inserten
DoInserts(connection, szLogExt);
return szCurrent2;
}
//------------------------------------------------
__forceinline LPSTR ReadLogLineCombined(CMySQL* connection, LPSTR szCurrent)
{
// Log-Format:
// 66.249.71.7 - - [20/Feb/2005:05:11:21 +0100] "GET /robots.txt HTTP/1.0" 200 2936 "-" "Googlebot/2.1 (+http://www.google.com/bot.html)"
ZeroMemory(&l, sizeof(l));
LPSTR szCurrent2 = strchr(szCurrent, '\n') + 1;
int register len = 0;
// ip
base = szCurrent;
point = strchr(base, ' ');
memcpy(l.ip, base, point-base);
base = point++;
ConvertIP(&l);
// datum
point = strchr(base, ']') + 1;
base = strchr(base, '[') + 1;
ZeroMemory(buf3, sizeof(buf3));
memcpy(buf3, base, point-base);
memcpy(tx1, buf3+3, 3);
tx1[3] = 0;
switch(tx1[0])
{
case 'J' :
if(tx1[1] == 'a')
d = 1;
else if (tx1[2] == 'l')
d = 7;
else d = 6;
break;
case 'F' :
d = 2;
break;
case 'M' :
if(tx1[2] == 'r')
d = 3;
else if (tx1[2] == 'y')
d = 5;
break;
case 'A' :
if(tx1[1] == 'p')
d = 4;
else
d = 8;
break;
case 'S' :
d = 9;
break;
case 'O' :
d = 10;
break;
case 'N' :
d = 11;
break;
case 'D' :
d = 12;
break;
}
sprintf(tx2, "%2.2d", d);
l.date[0] = buf3[7];
l.date[1] = buf3[8];
l.date[2] = buf3[9];
l.date[3] = buf3[10];
l.date[4] = '-';
l.date[5] = tx2[0];
l.date[6] = tx2[1];
l.date[7] = '-';
l.date[8] = buf3[0];
l.date[9] = buf3[1];
l.date[10] = ' ';
l.date[11] = buf3[12];
l.date[12] = buf3[13];
l.date[13] = buf3[14];
l.date[14] = buf3[15];
l.date[15] = buf3[16];
l.date[16] = buf3[17];
l.date[17] = buf3[18];
l.date[18] = buf3[19];
l.date[19] = 0;
// meth
base = point+2;
point = strchr(base, ' ');
memcpy(l.method, base, point-base);
base = point+1;
// uri
point = strchr(base, ' ') ;
ZeroMemory(buf3, sizeof(buf3));
len = point-base;
if(len > 255)
len=255;
memcpy(buf3, base, len);
mysql_real_escape_string(connection->GetConnectionHandle(), l.uri, buf3, lstrlen(buf3));
base = point + 2;
base = strchr(base, ' ') + 1;
// code
point = strchr(base, ' ') ;
memcpy(l.code, base, point-base);
base = ++point;
// groesse
point = strchr(base, ' ') ;
memcpy(l.size, base, point-base);
base = point+2;
// ref
point = strchr(base, '\"') ;
ZeroMemory(buf3, sizeof(buf3));
len = point-base;
if(len > 512)
len=512;
memcpy(buf3, base, len);
mysql_real_escape_string(connection->GetConnectionHandle(), l.referer, buf3, lstrlen(buf3));
base = point+3;
// ua
point = strchr(base, '\"') ;
ZeroMemory(buf3, sizeof(buf3));
len = point-base;
if(len > 255)
len=255;
memcpy(buf3, base, len);
mysql_real_escape_string(connection->GetConnectionHandle(), l.ua, buf3, lstrlen(buf3));
// jetzt inserten
DoInserts(connection, szLogExt);
return szCurrent2;
}
//------------------------------------------------
#define LOGFORMAT_1UND1 1
#define LOGFORMAT_COMBINED 2
__forceinline void LogToSQL(CMySQL* id_connect, LPCSTR lpszFile, UINT type=LOGFORMAT_1UND1)
{
printf("%s\r\n\r\n", lpszFile);
int iStartTime = GetTickCount();
HANDLE hf = CreateFile(lpszFile, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
DWORD dh;
DWORD reallen = ::GetFileSize(hf, &dh);
printf("Puffer: %d\r\n", reallen);
LPSTR szBuf = (LPSTR)malloc(reallen + 4096);
ZeroMemory(szBuf, reallen + 4096);
DWORD dwLen;
::ReadFile(hf, szBuf, reallen, &dwLen, NULL);
CloseHandle(hf);
LPSTR szCurrent = szBuf;
LPSTR szCurrentOld = NULL;
LPSTR lpszMax = szCurrent+dwLen-20;
int plus = 0;
if(LOGFORMAT_COMBINED == type)
{
while(szCurrent < lpszMax)
{
if(!szCurrent)
break;
szCurrent = ReadLogLineCombined(id_connect, szCurrent);
plus ++;
}
}
else if (LOGFORMAT_1UND1 == type)
{
while(szCurrent < lpszMax)
{
if(!szCurrent)
break;
szCurrent = ReadLogLine1und1(id_connect, szCurrent);
plus ++;
}
}
printf("%d Zeilen in %d msec\r\n\r\n", plus, GetTickCount()-iStartTime);
//---------------
free(szBuf);
}
//------------------------------------------------
int main(int argc, char* argv[])
{
unsigned int i = 0;
unsigned long numRows = 0;
ZeroMemory(szOldUA, sizeof(szOldUA));
ZeroMemory(szLogExtOld, sizeof(szLogExtOld));
CMySQL connection("127.0.0.1","root","pwd", "logs");
// altes beseitigen
// connection.Query("truncate logs;");
// connection.Query("truncate ua;");
LogToSQL(&connection, "c:\\access.log");
connection.Close();
return 0;
}
gibt mit Compiler-Optionen /G6 /Ox . Das geht