Further changes on the way to 1.17, big one was the segfault fix.
|
diff --git a/CHANGELOG b/CHANGELOG index 24e56a1..8f53074 100644 --- a/ CHANGELOG+++ b/ CHANGELOG |
| @@ -1,4 +1,4 @@ |
| 1 | $Id: CHANGELOG,v 1.11 2002/05/14 21:47:14 helios Exp $ |
1 | $Id: CHANGELOG,v 1.12 2002/05/16 21:35:12 helios Exp $ |
| 2 | |
2 | |
| 3 | |
3 | |
| 4 | TODO: |
4 | TODO: |
| @@ -8,7 +8,8 @@ TODO: |
| 8 | * check for mandatory conf directives / syntax quit if not |
8 | * check for mandatory conf directives / syntax quit if not |
| 9 | * merge server config into vh config |
9 | * merge server config into vh config |
| 10 | * port to Apache 2.x |
10 | * port to Apache 2.x |
| 11 | |
11 | * does determining table name in massvirtual mode upon every request |
| |
12 | cause performance degradation? If so fix. |
| 12 | |
13 | |
| 13 | CHANGES: |
14 | CHANGES: |
| 14 | |
15 | |
| @@ -32,6 +33,10 @@ CHANGES: |
| 32 | really dumb, and people have requested this change. |
33 | really dumb, and people have requested this change. |
| 33 | * Better checking in the extract_cookie routine. Before, it could |
34 | * Better checking in the extract_cookie routine. Before, it could |
| 34 | segfault if a person specified "c" but didn't define MySQLWhichCookie. |
35 | segfault if a person specified "c" but didn't define MySQLWhichCookie. |
| |
36 | * Some code reorg/renaming for clarity and to support the new direction |
| |
37 | of database inspecificity. More to come. |
| |
38 | * Simplified error messages. |
| |
39 | * Table creation now uses safe_mysql_query and checks the result. |
| 35 | |
40 | |
| 36 | |
41 | |
| 37 | 1.16: |
42 | 1.16: |
|
|
|
| @@ -1,4 +1,4 @@ |
| 1 | /* $Id: mod_log_sql.c,v 1.12 2002/05/14 21:47:15 helios Exp $ */ |
1 | /* $Id: mod_log_sql.c,v 1.13 2002/05/16 21:35:12 helios Exp $ */ |
| 2 | |
2 | |
| 3 | /* --------* |
3 | /* --------* |
| 4 | * DEFINES * |
4 | * DEFINES * |
| @@ -76,7 +76,7 @@ typedef struct { |
| 76 | char *transfer_log_format; |
76 | char *transfer_log_format; |
| 77 | char *preserve_file; |
77 | char *preserve_file; |
| 78 | char *cookie_name; |
78 | char *cookie_name; |
| 79 | } log_mysql_state; |
79 | } log_sql_state; |
| 80 | |
80 | |
| 81 | |
81 | |
| 82 | /* -----------------* |
82 | /* -----------------* |
| @@ -322,7 +322,7 @@ static const char *extract_cookie(request_rec *r, char *a) |
| 322 | char *isvalid; |
322 | char *isvalid; |
| 323 | char *cookiebuf; |
323 | char *cookiebuf; |
| 324 | |
324 | |
| 325 | log_mysql_state *cls = get_module_config(r->server->module_config, &mysql_log_module); |
325 | log_sql_state *cls = get_module_config(r->server->module_config, &mysql_log_module); |
| 326 | |
326 | |
| 327 | if (cls->cookie_name != NULL) { |
327 | if (cls->cookie_name != NULL) { |
| 328 | #ifdef DEBUG |
328 | #ifdef DEBUG |
| @@ -423,13 +423,13 @@ static const char *extract_unique_id(request_rec *r, char *a) |
| 423 | |
423 | |
| 424 | |
424 | |
| 425 | |
425 | |
| 426 | struct log_mysql_item_list { |
426 | struct log_sql_item_list { |
| 427 | char ch; /* its letter code */ |
427 | char ch; /* its letter code */ |
| 428 | item_key_func func; /* its extraction function */ |
428 | item_key_func func; /* its extraction function */ |
| 429 | const char *sql_field_name; /* its column in SQL */ |
429 | const char *sql_field_name; /* its column in SQL */ |
| 430 | int want_orig_default; /* if it requires the original request prior to internal redirection */ |
430 | int want_orig_default; /* if it requires the original request prior to internal redirection */ |
| 431 | int string_contents; /* if it returns a string */ |
431 | int string_contents; /* if it returns a string */ |
| 432 | } log_mysql_item_keys[] = { |
432 | } log_sql_item_keys[] = { |
| 433 | |
433 | |
| 434 | { 'A', extract_agent, "agent", 1, 1 }, |
434 | { 'A', extract_agent, "agent", 1, 1 }, |
| 435 | { 'b', extract_bytes_sent, "bytes_sent", 0, 0 }, |
435 | { 'b', extract_bytes_sent, "bytes_sent", 0, 0 }, |
| @@ -553,11 +553,11 @@ const char *extract_table(void *data, const char *key, const char *val) |
| 553 | void preserve_entry(request_rec *r, const char *query) |
553 | void preserve_entry(request_rec *r, const char *query) |
| 554 | { |
554 | { |
| 555 | FILE *fp; |
555 | FILE *fp; |
| 556 | log_mysql_state *cls = get_module_config(r->server->module_config, &mysql_log_module); |
556 | log_sql_state *cls = get_module_config(r->server->module_config, &mysql_log_module); |
| 557 | |
557 | |
| 558 | fp = pfopen(r->pool, cls->preserve_file, "a"); |
558 | fp = pfopen(r->pool, cls->preserve_file, "a"); |
| 559 | if (fp == NULL) |
559 | if (fp == NULL) |
| 560 | ap_log_error(APLOG_MARK,ERRLEVEL,r->server,"attempted append of local offline file but failed."); |
560 | ap_log_error(APLOG_MARK,ERRLEVEL,r->server,"mod_log_sql: attempted append of local preserve file but failed."); |
| 561 | else { |
561 | else { |
| 562 | fprintf(fp,"%s;\n", query); |
562 | fprintf(fp,"%s;\n", query); |
| 563 | pfclose(r->pool, fp); |
563 | pfclose(r->pool, fp); |
| @@ -565,7 +565,7 @@ void preserve_entry(request_rec *r, const char *query) |
| 565 | } |
565 | } |
| 566 | |
566 | |
| 567 | /*-----------------------------------------------------*/ |
567 | /*-----------------------------------------------------*/ |
| 568 | /* safe_mysql_query: perform a database insert with */ |
568 | /* safe_mysql_query: perform a database query with */ |
| 569 | /* a degree of safety and error checking. */ |
569 | /* a degree of safety and error checking. */ |
| 570 | /* */ |
570 | /* */ |
| 571 | /* Parms: request record, SQL insert statement */ |
571 | /* Parms: request record, SQL insert statement */ |
| @@ -577,7 +577,6 @@ int safe_mysql_query(request_rec *r, const char *query) |
| 577 | int retval; |
577 | int retval; |
| 578 | struct timespec delay, remainder; |
578 | struct timespec delay, remainder; |
| 579 | int ret; |
579 | int ret; |
| 580 | char *str; |
| |
| 581 | void (*handler) (int); |
580 | void (*handler) (int); |
| 582 | |
581 | |
| 583 | |
582 | |
| @@ -585,53 +584,54 @@ int safe_mysql_query(request_rec *r, const char *query) |
| 585 | handler = signal(SIGPIPE, SIG_IGN); |
584 | handler = signal(SIGPIPE, SIG_IGN); |
| 586 | |
585 | |
| 587 | /* First attempt for the query */ |
586 | /* First attempt for the query */ |
| 588 | retval = mysql_query(mysql_log, query); |
587 | if (mysql_log != NULL) |
| 589 | |
588 | retval = mysql_query(mysql_log, query); |
| |
589 | else |
| |
590 | return 1; |
| |
591 | |
| 590 | /* If we ran the query and it returned an error, try to be graceful. |
592 | /* If we ran the query and it returned an error, try to be graceful. |
| 591 | * We only reach this point if the module thinks it has a valid connection to the |
593 | * (The module thought it had a valid mysql_log connection but the query |
| 592 | * database (i.e. mysql_log is non-null). But that connection could go sour |
594 | * might have failed, so we have to check.) |
| 593 | * at any time, hence the check. */ |
595 | */ |
| 594 | if ( retval != 0 ) |
596 | if ( retval != 0 ) |
| 595 | { |
597 | { |
| 596 | log_mysql_state *cls = get_module_config(r->server->module_config, &mysql_log_module); |
598 | log_sql_state *cls = get_module_config(r->server->module_config, &mysql_log_module); |
| 597 | |
599 | |
| 598 | /* Something went wrong, so start by trying to restart the db link. */ |
600 | /* Something went wrong, so start by trying to restart the db link. */ |
| 599 | ap_log_error(APLOG_MARK,ERRLEVEL,r->server,"attempting reconnect because API said: %s", mysql_error(mysql_log)); |
601 | ap_log_error(APLOG_MARK,ERRLEVEL,r->server,"mod_log_sql: first attempt failed, API said: %s", MYSQL_ERROR(mysql_log)); |
| 600 | |
602 | |
| 601 | mysql_log = NULL; |
603 | mysql_log = NULL; |
| 602 | open_logdb_link(); |
604 | open_logdb_link(); |
| 603 | |
605 | |
| 604 | if (mysql_log == NULL) { /* still unable to link */ |
606 | if (mysql_log == NULL) { /* still unable to link */ |
| 605 | signal(SIGPIPE, handler); |
607 | signal(SIGPIPE, handler); |
| 606 | ap_log_error(APLOG_MARK,ERRLEVEL,r->server,"httpd child reconnect failed, unable to reach database. SQL logging stopped until an httpd child regains a db connection."); |
608 | ap_log_error(APLOG_MARK,ERRLEVEL,r->server,"mod_log_sql: reconnect failed, unable to reach database. SQL logging stopped until child regains a db connection."); |
| 607 | ap_log_error(APLOG_MARK,ERRLEVEL,r->server,"log entries are being preserved in %s", cls->preserve_file); |
609 | ap_log_error(APLOG_MARK,ERRLEVEL,r->server,"mod_log_sql: log entries are being preserved in %s", cls->preserve_file); |
| 608 | preserve_entry(r, query); |
610 | preserve_entry(r, query); |
| 609 | return retval; |
611 | return retval; |
| 610 | } else { |
612 | } else { |
| 611 | ap_log_error(APLOG_MARK,ERRLEVEL,r->server,"reconnect successful."); |
613 | ap_log_error(APLOG_MARK,ERRLEVEL,r->server,"mod_log_sql: reconnect successful"); |
| 612 | } |
614 | } |
| 613 | |
| |
| 614 | /* Attempt a single re-try... First sleep for a tiny amount of time. */ |
| |
| 615 | delay.tv_sec = 0; |
| |
| 616 | delay.tv_nsec = 250000000; /* max is 999999999 (nine nines) */ |
| |
| 617 | ret = nanosleep(&delay, &remainder); |
| |
| 618 | if (ret && errno != EINTR) |
| |
| 619 | ap_log_error(APLOG_MARK,ERRLEVEL,r->server,"nanosleep unsuccessful."); |
| |
| 620 | |
| |
| 621 | /* Now make our second attempt */ |
| |
| 622 | retval = mysql_query(mysql_log,query); |
| |
| 623 | |
| |
| 624 | /* If this one also failed, log that and append to our local offline file */ |
| |
| 625 | if ( retval != 0 ) |
| |
| 626 | { |
| |
| 627 | str = ap_pstrcat(r->pool, "delayed insert attempt failed, API said: ", MYSQL_ERROR(mysql_log), NULL); |
| |
| 628 | ap_log_error(APLOG_MARK,ERRLEVEL,r->server,str); |
| |
| 629 | |
615 | |
| 630 | preserve_entry(r, query); |
616 | /* Attempt a single re-try... First sleep for a tiny amount of time. */ |
| 631 | ap_log_error(APLOG_MARK,ERRLEVEL,r->server,"entry preserved in %s", cls->preserve_file); |
617 | delay.tv_sec = 0; |
| 632 | } else { |
618 | delay.tv_nsec = 250000000; /* max is 999999999 (nine nines) */ |
| 633 | ap_log_error(APLOG_MARK,ERRLEVEL,r->server,"insert successful after a delayed retry."); |
619 | ret = nanosleep(&delay, &remainder); |
| 634 | } |
620 | if (ret && errno != EINTR) |
| |
621 | ap_log_error(APLOG_MARK,ERRLEVEL,r->server,"mod_log_sql: nanosleep unsuccessful"); |
| |
622 | |
| |
623 | /* Now make our second attempt */ |
| |
624 | retval = mysql_query(mysql_log,query); |
| |
625 | |
| |
626 | /* If this one also failed, log that and append to our local offline file */ |
| |
627 | if ( retval != 0 ) |
| |
628 | { |
| |
629 | ap_log_error(APLOG_MARK,ERRLEVEL,r->server,"mod_log_sql: second attempt failed, API said: %s", MYSQL_ERROR(mysql_log)); |
| |
630 | preserve_entry(r, query); |
| |
631 | ap_log_error(APLOG_MARK,ERRLEVEL,r->server,"mod_log_sql: entry preserved in %s", cls->preserve_file); |
| |
632 | } else { |
| |
633 | ap_log_error(APLOG_MARK,ERRLEVEL,r->server,"mod_log_sql: second attempt successful"); |
| |
634 | } |
| 635 | } |
635 | } |
| 636 | |
636 | |
| 637 | /* Restore SIGPIPE to its original handler function */ |
637 | /* Restore SIGPIPE to its original handler function */ |
| @@ -646,43 +646,43 @@ int safe_mysql_query(request_rec *r, const char *query) |
| 646 | * to the directives found at Apache runtime. * |
646 | * to the directives found at Apache runtime. * |
| 647 | * ------------------------------------------------*/ |
647 | * ------------------------------------------------*/ |
| 648 | |
648 | |
| 649 | const char *set_mysql_massvirtual(cmd_parms *parms, void *dummy, int flag) |
649 | const char *set_log_sql_massvirtual(cmd_parms *parms, void *dummy, int flag) |
| 650 | { |
650 | { |
| 651 | massvirtual = ( flag ? 1 : 0); |
651 | massvirtual = ( flag ? 1 : 0); |
| 652 | return NULL; |
652 | return NULL; |
| 653 | } |
653 | } |
| 654 | |
654 | |
| 655 | const char *set_log_mysql_create(cmd_parms *parms, void *dummy, int flag) |
655 | const char *set_log_sql_create(cmd_parms *parms, void *dummy, int flag) |
| 656 | { |
656 | { |
| 657 | create_tables = ( flag ? 1 : 0); |
657 | create_tables = ( flag ? 1 : 0); |
| 658 | return NULL; |
658 | return NULL; |
| 659 | } |
659 | } |
| 660 | |
660 | |
| 661 | const char *set_log_mysql_db(cmd_parms *parms, void *dummy, char *arg) |
661 | const char *set_log_sql_db(cmd_parms *parms, void *dummy, char *arg) |
| 662 | { |
662 | { |
| 663 | db_name = arg; |
663 | db_name = arg; |
| 664 | return NULL; |
664 | return NULL; |
| 665 | } |
665 | } |
| 666 | |
666 | |
| 667 | const char *set_log_mysql_cookie(cmd_parms *parms, void *dummy, char *arg) |
667 | const char *set_log_sql_cookie(cmd_parms *parms, void *dummy, char *arg) |
| 668 | { |
668 | { |
| 669 | log_mysql_state *cls = get_module_config(parms->server->module_config, &mysql_log_module); |
669 | log_sql_state *cls = get_module_config(parms->server->module_config, &mysql_log_module); |
| 670 | |
670 | |
| 671 | cls->cookie_name = arg; |
671 | cls->cookie_name = arg; |
| 672 | return NULL; |
672 | return NULL; |
| 673 | } |
673 | } |
| 674 | |
674 | |
| 675 | const char *set_log_mysql_preserve_file(cmd_parms *parms, void *dummy, char *arg) |
675 | const char *set_log_sql_preserve_file(cmd_parms *parms, void *dummy, char *arg) |
| 676 | { |
676 | { |
| 677 | /* char *pfile; */ |
677 | /* char *pfile; */ |
| 678 | log_mysql_state *cls = get_module_config(parms->server->module_config, &mysql_log_module); |
678 | log_sql_state *cls = get_module_config(parms->server->module_config, &mysql_log_module); |
| 679 | |
679 | |
| 680 | /* pfile = ap_pstrcat(parms->pool, "/tmp/", arg, NULL); */ |
680 | /* pfile = ap_pstrcat(parms->pool, "/tmp/", arg, NULL); */ |
| 681 | cls->preserve_file = arg; |
681 | cls->preserve_file = arg; |
| 682 | return NULL; |
682 | return NULL; |
| 683 | } |
683 | } |
| 684 | |
684 | |
| 685 | const char *set_log_mysql_info(cmd_parms *parms, void *dummy, char *host, char *user, char *pwd) |
685 | const char *set_log_sql_info(cmd_parms *parms, void *dummy, char *host, char *user, char *pwd) |
| 686 | { |
686 | { |
| 687 | if (*host != '.') { |
687 | if (*host != '.') { |
| 688 | db_host = host; |
688 | db_host = host; |
| @@ -696,37 +696,37 @@ const char *set_log_mysql_info(cmd_parms *parms, void *dummy, char *host, char * |
| 696 | return NULL; |
696 | return NULL; |
| 697 | } |
697 | } |
| 698 | |
698 | |
| 699 | const char *set_transfer_log_mysql_table(cmd_parms *parms, void *dummy, char *argef='/httpd/mod_log_sql/tree/INSTALL?id=78adb60ccfd9497d5fbc899674ab1263609933b6#n189'>189 | 10) If you compiled mod_log_sql with the ability to make its own tables |
244 | mysql> grant insert,create on apachelogs.* to loguser@my.apachemachine.com identified by 'l0gger'; |
| 190 | then you can skip this step. Otherwise you need to do it by hand: |
| |
| 191 | |
245 | |
| 192 | Create a database and table to hold the new log data. I log the |
246 | You may be especially security-paranoid and not want "loguser" to have |
| 193 | same data as the regular "combined log" plus a little extra information |
247 | "create" capability within the "apachelogs" databse. You can disable that |
| 194 | that can be useful. |
248 | but the cost is that you cannot use the module's automatic-table-creation |
| |
249 | feature. If that's an acceptable cost, hand-create the tables as described |
| |
250 | in step 1 and use the following GRANT statement instead of the one above: |
| 195 | |
251 | |
| 196 | The order that the fields appear in the table is irrelevant |
252 | mysql> grant insert on apachelogs.* to loguser@my.apachemachine.com identified by 'l0gger'; |
| 197 | because you can SELECT them in any order you choose. To create |
| |
| 198 | this table I first created a new database called "apache": |
| |
| 199 | |
253 | |
| 200 | # mysql -uadmin -pmypassword |
254 | 3) Enable full logging of your MySQL daemon (at least temporarily |
| 201 | mysql> create database apache; |
255 | for debugging purposes) if you don't do this already: |
| 202 | |
256 | |
| 203 | Then create the table called "access_log". I enclosed an SQL file |
257 | Edit /etc/my.cnf and add the following line to your [mysqld] section: |
| 204 | that will create every column type that mod_log_sql supports. |
| |
| 205 | Unless you're just testing or playing around, this is probably NOT |
| |
| 206 | what you want, so edit the file first and delete the lines that |
| |
| 207 | don't pertain to you. Then: |
| |
| 208 | |
258 | |
| 209 | mysql> source access_log.sql |
259 | log=/var/log/mysql-messages |
| 210 | |
260 | |
| |
261 | Then restart MySQL. |
| 211 | |
262 | |
| 212 | 11) Create a specific MySQL userid that httpd will use to authenticate |
263 | 4) Tell the module what database to use and the appropriate authentication |
| 213 | and enter data. This userid need not be an actual Unix user. It |
264 | information. |
| 214 | is a userid internal to MySQL with specific privileges. |
| |
| 215 | |
| |
| 216 | mysql> grant insert,create on apache.* to loguser@my.apachemachine.com identified by 'l0gger'; |
| |
| 217 | |
| |
| 218 | Security is a very real concern. mod_log_sql by default is |
| |
| 219 | set up to create the SQL tables it needs. If you have deactivated |
| |
| 220 | this capability, then create a user called "loguser" with the password |
| |
| 221 | "l0gger" with only the capability of INSERT to "access_log": |
| |
| 222 | |
265 | |
| 223 | mysql> grant insert on apache.access_log to loguser@my.apachemachine.com identified by 'l0gger'; |
266 | OUR EXAMPLE: use the MySQL database called "apachelogs" running |
| |
267 | on "dbmachine.foo.com". The module uses username "loguser" and |
| |
268 | password "l0gger" to authenticate to the database. The log entries |
| |
269 | will be INSERTed into the table called "access_log". |
| 224 | |
270 | |
| |
271 | So, edit httpd.conf and insert the following lines somewhere AFTER any |
| |
272 | LoadModule / AddModule statements. Make sure these statements are |
| |
273 | "global," i.e. not inside any VirtualHost stanza. |
| 225 | |
274 | |
| 226 | 12) Enable full logging of your MySQL daemon (at least temporarily |
275 | LogSQLDatabase apachelogs |
| 227 | for debugging purposes) if you don't do this already: |
276 | LogSQLLoginInfo dbmachine.foo.com loguser l0gger |
| |
277 | LogSQLCreateTables on |
| 228 | |
278 | |
| 229 | Edit /etc/my.cnf and add the following line to your [mysqld] section: |
279 | If your database resides on localhost instead of another host, specify |
| |
280 | the MySQL server's socket file as follows: |
| 230 | |
281 | |
| 231 | log=/var/log/mysql-messages |
282 | LogSQLSocketFile /your/path/to/mysql.sock |
| 232 | |
283 | |
| 233 | Then restart MySQL. |
284 | 5) The actual logging is set up on a virtual-host-by-host basis. So, |
| |
285 | skip down to the virtual host you want to set up. The LogSQLTransferLogTable |
| |
286 | directive is the minimum required to log -- other directives simply |
| |
287 | tune the module's behavior. |
| 234 | |
288 | |
| 235 | 13) Restart apache. |
289 | <VirtualHost 1.2.3.4> |
| |
290 | [snip] |
| |
291 | |
| |
292 | LogSQLTransferLogTable access_log |
| |
293 | |
| |
294 | [snip] |
| |
295 | </VirtualHost> |
| |
296 | |
| |
297 | 6) Restart apache. |
| 236 | |
298 | |
| 237 | # /etc/rc.d/init.d/httpd start |
299 | # /etc/rc.d/init.d/httpd start |
| 238 | |
300 | |
| 239 | 13) Load your web site in a browser to trigger some hits, then confirm that |
301 | 7) Load your web site in a browser to trigger some hits, then confirm that |
| 240 | the entries are being successfully logged: |
302 | the entries are being successfully logged: |
| 241 | |
303 | |
| 242 | # mysql -hmysql.host.com -umysqladmin -p -e "select * from access_log" apache; |
304 | # mysql -hmysql.host.com -umysqladmin -p -e "select * from access_log" apachelogs |
| 243 | Enter password: |
305 | Enter password: |
| 244 | |
306 | |
| 245 | +---------------------------------------------------+-------------+-------------+------------------+------------------+------------+--------+------------+------------------------------------+ |
307 | +---------------------------------------------------+-------------+-------------+------------------+------------------+------------+--------+------------+------------------------------------+ |
| @@ -251,10 +313,29 @@ Installation (as a static module compiled into httpd) |
| 251 | . |
313 | . |
| 252 | +---------------------------------------------------+-------------+-------------+------------------+------------------+------------+--------+------------+------------------------------------+ |
314 | +---------------------------------------------------+-------------+-------------+------------------+------------------+------------+--------+------------+------------------------------------+ |
| 253 | |
315 | |
| 254 | 14) You have basic functionality. Don't disable your regular Apache logs until |
316 | You have basic functionality. Don't disable your regular Apache logs until |
| 255 | you feel comfortable that the database is behaving as you'd like and that |
317 | you feel comfortable that the database is behaving as you'd like and that |
| 256 | things are going well. |
318 | things are going well. |
| 257 | |
319 | |
| 258 | |
320 | 8) If you do not see any entries in the access_log, then something is preventing |
| 259 | |
321 | the inserts from happening. This problem could be caused by several things: |
| 260 | |
322 | - Improper privileges set up in the MySQL database |
| |
323 | - You aren't hitting a VirtualHost that has a LogSQLTransferLogTable entry |
| |
324 | - You didn't specify the right host |
| |
325 | |
| |
326 | If you have confirmed your LogSQL* directives and know them to be correct, |
| |
327 | you should examine the httpd server logs for mod_log_sql messages; the module |
| |
328 | will offer hints as to why it cannot connect, etc. Also examine the MySQL |
| |
329 | log that you established in step 3. Ensure that the INSERTs are not being |
| |
330 | rejected because of a malformed table entry or other clerical error. If you |
| |
331 | see no INSERT attempts in the log, the module isn't successfully connecting |
| |
332 | to the database. |
| |
333 | |
| |
334 | The next thing to do is recompile the module with debugging output activated. |
| |
335 | change the "#undef DEBUG" on line 8 of mod_log_sql.c to "#define DEBUG" and |
| |
336 | recompile/reinstall. The module will now output copious notes about what |
| |
337 | it is doing, and this will help you (and the maintainer) solve the problem. |
| |
338 | |
| |
339 | 9) You can now activate the advanced features of mod_log_sql. These are all |
| |
340 | described in the online directive documentation: |
| |
341 | http://www.grubbybaby.com/mod_log_sql/directives.html |
|