2013-04-04 18 views
1

我有一個PHP應用程序,它爲多個用戶使用單個數據庫。用戶登錄,他們的ID存儲在一個會話中,他們使用應用程序來檢索或更新數據庫中的數據。以每個用戶爲基礎記錄所有MySQL事務

爲了安全/存檔的目的,我想每個用戶都記錄每個SQL事務。請注意,「用戶」不是MySQL用戶,因爲他們只使用一個用戶。我該怎麼做呢?

我目前正在運行Centos 5.8,PHP 5.3.18和MySQL 5.5。

感謝

回答

0
$sql = "UPDATE table SET col = ?" 
$db->prepare($sql); 
//some params etc... 
$filename = '/dir/logs/log-' . $_SESSION['username'] . ''; 
$handle = fopen($filename, "wr"); 
$db->execute(); 
fwrite($handle, $sql); 

這是一個簡單的例子,你如何使用查詢無論是執行和在一個文件中,用戶命名的寫作。那麼,用這種方法,也許你會在執行前得到$ sql的內容,但我認爲你有這個想法。

P.S:THX爲編輯:)

+0

爲什麼要登錄到文件?由於您已經在使用數據庫,因此請記錄到包含timestamp,user-id和SQL語句(以及可能的其他字段)等額外字段的表中,並將SQL存儲在該表中。這樣,您可以使用SQL來過濾日誌,這比將日誌存儲在文件中肯定更加強大/靈活。 – user13955 2013-04-04 13:13:30

+0

您可能是對的,但我認爲它應該在另一個數據庫上,因爲這個是由多個用戶使用的,這對於肯定有更新權限,並且可以很容易地操縱日誌 – 2013-04-04 13:16:22

+0

他說PHP * application *,所以應該因爲大概數據庫只能被應用程序訪問,所以用戶不能直接寫入。 – user13955 2013-04-04 13:18:14

0

您可以配置MySQL產生General query log(GQL)。此日誌記錄了從所有客戶端收到的已建立的客戶端連接和語句。它是一個常規的文本日誌文件,它按照它們接收的順序記錄每個針對您DBMS的命令。它包含時間戳,標識,命令和參數。

IP地址和會話不存在,因爲數據庫請求通過服務器在本地運行。時間戳允許從您的Web服務器與客戶端的IP條目進行非常精確的匹配,即Apache httpd或Tomcat Access log file(ALF)。

我們使用GQL來增強由GWT Web應用程序產生的稀疏ALF信息。

此示例一般查詢日誌應該給你的想法:

110602 12:55:20  3 Connect [email protected] on w2p 
      3 Query /* mysql-connector-java-5.1.15 (Revision: ${bzr.revision-id}) */SHOW VARIABLES WHERE Variable_name ='language' OR Variable_name = 'net_write_timeout' OR Variable_name = 'interactive_timeout' OR Variable_name = 'wait_timeout' OR Variable_name = 'character_set_client' OR Variable_name = 'character_set_connection' OR Variable_name = 'character_set' OR Variable_name = 'character_set_server' OR Variable_name = 'tx_isolation' OR Variable_name = 'transaction_isolation' OR Variable_name = 'character_set_results' OR Variable_name = 'timezone' OR Variable_name = 'time_zone' OR Variable_name = 'system_time_zone' OR Variable_name = 'lower_case_table_names' OR Variable_name = 'max_allowed_packet' OR Variable_name = 'net_buffer_length' OR Variable_name = 'sql_mode' OR Variable_name = 'query_cache_type' OR Variable_name = 'query_cache_size' OR Variable_name = 'init_connect' 
110602 12:55:21  3 Query /* mysql-connector-java-5.1.15 (Revision: ${bzr.revision-id}) */SELECT @@session.auto_increment_increment 
      3 Query SHOW COLLATION 
      3 Query SET NAMES utf8mb4 
      3 Query SET character_set_results = NULL 
      3 Query SET autocommit=1 
      3 Query select * from user where username = 'asdasd' and password = 'aa' 
      1 Query show global status 
110602 12:55:25  1 Query show global status 
110602 12:55:30 3 Query select * from user where username = 'costis' and password = 'snafu' 
+0

您會如何建議鏈接GQL到實際用戶?這是通過與ALF比較來完成的嗎? – user1032531 2013-04-04 13:26:21

+0

沒錯。您從ALF獲取IP地址,並從GQL獲取用戶名。 – 2013-04-04 13:28:53

+0

我對Tomcat ALF一無所知。我需要學習嗎?我看過我的Apache/var/httpd/access_log文件,但沒有看到我如何將它與MYSQL日誌相關聯。 – user1032531 2013-04-04 13:38:49

0

您可以打開和閱讀MySQL general query log。它包含了所有類似的疑問:

... 
130404 19:02:50 476 Connect [email protected] on test 
      476 Query SET NAMES utf8 
      476 Query SELECT * FROM `table1` 
130404 19:02:52 476 Quit 
130404 19:03:33 477 Connect [email protected] on test 
      477 Query SET NAMES utf8 
... 

476,477等都是MySQL的線程ID。每個新的連接都擁有它的ID。 所有你需要知道的你的用戶線程ID。對於PHP mysqli擴展,你可以使用mysqli_thread_id()

echo $_SESSION['username'].' '. 
    date('Y-m-d H:i:s').' '. 
    mysqli_thread_id($link); 

商店此值介於日誌相匹配。

+0

MySQL線程ID是一種很好的方法,但我對使用MySQL通用查詢日誌持懷疑態度。 – user1032531 2013-04-04 15:13:50

相關問題