Merge lp:~sergei.glushchenko/percona-server/5.5-ps-bug1320879 into lp:percona-server/5.5

Proposed by Sergei Glushchenko
Status: Merged
Approved by: Laurynas Biveinis
Approved revision: no longer in the source branch.
Merged at revision: 681
Proposed branch: lp:~sergei.glushchenko/percona-server/5.5-ps-bug1320879
Merge into: lp:percona-server/5.5
Diff against target: 1258 lines (+664/-298)
6 files modified
mysql-test/include/audit_log_events.inc (+3/-1)
mysql-test/r/audit_log.result (+303/-145)
mysql-test/t/audit_log.test (+75/-21)
plugin/audit_log/audit_log.c (+239/-99)
plugin/audit_log/file_logger.c (+38/-29)
plugin/audit_log/logger.h (+6/-3)
To merge this branch: bzr merge lp:~sergei.glushchenko/percona-server/5.5-ps-bug1320879
Reviewer Review Type Date Requested Status
Laurynas Biveinis (community) Approve
Review via email: mp+220912@code.launchpad.net

This proposal supersedes a proposal from 2014-05-23.

Description of the change

Bug 1320879: multiple issues when checking audit.log with xmllint
- fixed XML attribute names
- wrapped log by XML tag <audit>
- added XML declaration at the beginning of the file
- expanded test case to verify log with XML parser
- escape not only query text but also other string values
This makes xmllint to stop complaining and also makes
mysqlauditgrep from MySQL tools to work with audit log generated
by PS audit log plugin.
Blueprint
https://blueprints.launchpad.net/percona-server/+spec/audit-log-csv-json
- variable audit_log_format to accept additional options JSON and CSV
- expanded test case to produce JSON and CSV logs and validate them

http://jenkins.percona.com/view/PS%205.5/job/percona-server-5.5-param/1000/

To post a comment you must log in.
Revision history for this message
Laurynas Biveinis (laurynas-biveinis) wrote : Posted in a previous version of this proposal

Wrong target branch?

review: Needs Resubmitting
Revision history for this message
Sergei Glushchenko (sergei.glushchenko) wrote :

Yes, it was wrong branch.

Revision history for this message
Laurynas Biveinis (laurynas-biveinis) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'mysql-test/include/audit_log_events.inc'
--- mysql-test/include/audit_log_events.inc 2014-05-14 14:32:33 +0000
+++ mysql-test/include/audit_log_events.inc 2014-05-26 07:58:11 +0000
@@ -2,7 +2,9 @@
22
3CREATE TABLE t1 (c1 INT, c2 CHAR(20));3CREATE TABLE t1 (c1 INT, c2 CHAR(20));
4--error ER_TABLE_EXISTS_ERROR4--error ER_TABLE_EXISTS_ERROR
5CREATE TABLE t1 (c1 INT, c2 CHAR(20));5CREATE TABLE t1
6 (c1 INT,
7 c2 CHAR(20));
6INSERT INTO t1 VALUES (1,'a'),(2,'b'),(3,'c');8INSERT INTO t1 VALUES (1,'a'),(2,'b'),(3,'c');
7SELECT * FROM t1;9SELECT * FROM t1;
8--error ER_NO_SUCH_TABLE10--error ER_NO_SUCH_TABLE
911
=== modified file 'mysql-test/r/audit_log.result'
--- mysql-test/r/audit_log.result 2014-05-14 14:32:33 +0000
+++ mysql-test/r/audit_log.result 2014-05-26 07:58:11 +0000
@@ -1,146 +1,304 @@
1CREATE TABLE t1 (c1 INT, c2 CHAR(20));1CREATE TABLE t1 (c1 INT, c2 CHAR(20));
2CREATE TABLE t1 (c1 INT, c2 CHAR(20));2CREATE TABLE t1
3ERROR 42S01: Table 't1' already exists3(c1 INT,
4INSERT INTO t1 VALUES (1,'a'),(2,'b'),(3,'c');4c2 CHAR(20));
5SELECT * FROM t1;5ERROR 42S01: Table 't1' already exists
6c1 c26INSERT INTO t1 VALUES (1,'a'),(2,'b'),(3,'c');
71 a7SELECT * FROM t1;
82 b8c1 c2
93 c91 a
10SELECT * FROM t2;102 b
11ERROR 42S02: Table 'test.t2' doesn't exist113 c
12DROP TABLE t1;12SELECT * FROM t2;
13PREPARE stmt1 FROM 'SELECT 1';13ERROR 42S02: Table 'test.t2' doesn't exist
14EXECUTE stmt1;14DROP TABLE t1;
15115PREPARE stmt1 FROM 'SELECT 1';
16116EXECUTE stmt1;
17SHOW STATUS LIKE 'audit_log%';171
18Variable_name Value181
19DEALLOCATE PREPARE stmt1;19SHOW STATUS LIKE 'audit_log%';
20show variables like 'audit_log%';20Variable_name Value
21Variable_name Value21DEALLOCATE PREPARE stmt1;
22audit_log_buffer_size 409622show variables like 'audit_log%';
23audit_log_file test_audit.log23Variable_name Value
24audit_log_flush OFF24audit_log_buffer_size 4096
25audit_log_format OLD25audit_log_file test_audit.log
26audit_log_policy ALL26audit_log_flush OFF
27audit_log_rotate_on_size 027audit_log_format OLD
28audit_log_rotations 028audit_log_policy ALL
29audit_log_strategy ASYNCHRONOUS29audit_log_rotate_on_size 0
30connect(localhost,no_such_user,,mysql,MASTER_PORT,MASTER_SOCKET);30audit_log_rotations 0
31ERROR 28000: Access denied for user 'no_such_user'@'localhost' (using password: NO)31audit_log_strategy ASYNCHRONOUS
32create table t1 (id int);32connect(localhost,no_such_user,,mysql,MASTER_PORT,MASTER_SOCKET);
33create table t2 (id int);33ERROR 28000: Access denied for user 'no_such_user'@'localhost' (using password: NO)
34insert into t1 values (1), (2);34create table t1 (id int);
35insert into t2 values (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2);35create table t2 (id int);
36select * from t1;36insert into t1 values (1), (2);
37id37insert into t2 values (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2);
38138select * from t1;
39239id
40alter table t1 rename renamed_t1;401
41select * from t_doesnt_exist;412
42ERROR 42S02: Table 'test.t_doesnt_exist' doesn't exist42alter table t1 rename renamed_t1;
43syntax_error_query;43select * from t_doesnt_exist;
44ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'syntax_error_query' at line 144ERROR 42S02: Table 'test.t_doesnt_exist' doesn't exist
45drop table renamed_t1, t2;45syntax_error_query;
46show variables like 'audit_log%';46ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'syntax_error_query' at line 1
47Variable_name Value47drop table renamed_t1, t2;
48audit_log_buffer_size 409648show variables like 'audit_log%';
49audit_log_file test_audit.log49Variable_name Value
50audit_log_flush OFF50audit_log_buffer_size 4096
51audit_log_format OLD51audit_log_file test_audit.log
52audit_log_policy ALL52audit_log_flush OFF
53audit_log_rotate_on_size 053audit_log_format OLD
54audit_log_rotations 054audit_log_policy ALL
55audit_log_strategy ASYNCHRONOUS55audit_log_rotate_on_size 0
56create database sa_db;56audit_log_rotations 0
57create table t1 (id2 int);57audit_log_strategy ASYNCHRONOUS
58insert into t1 values (1), (2);58create database sa_db;
59select * from t1;59create table t1 (id2 int);
60id260insert into t1 values (1), (2);
61161select * from t1;
62262id2
63drop table t1;631
64use sa_db;642
65create table sa_t1(id int);65drop table t1;
66insert into sa_t1 values (1), (2);66use sa_db;
67drop table sa_t1;67create table sa_t1(id int);
68drop database sa_db;68insert into sa_t1 values (1), (2);
69create user 'jeffrey'@'localhost' IDENTIFIED BY 'mypass';69drop table sa_t1;
70drop user 'jeffrey'@'localhost';70drop database sa_db;
71select '&;&&&""""<><<>>>>';71create user 'jeffrey'@'localhost' IDENTIFIED BY 'mypass';
72&;&&&""""<><<>>>>72drop user 'jeffrey'@'localhost';
73&;&&&""""<><<>>>>73select '&;&&&""""<><<>>>>';
74CREATE TABLE t1 (c1 INT, c2 CHAR(20));74&;&&&""""<><<>>>>
75CREATE TABLE t1 (c1 INT, c2 CHAR(20));75&;&&&""""<><<>>>>
76ERROR 42S01: Table 't1' already exists76set global audit_log_flush= ON;
77INSERT INTO t1 VALUES (1,'a'),(2,'b'),(3,'c');77CREATE TABLE t1 (c1 INT, c2 CHAR(20));
78SELECT * FROM t1;78CREATE TABLE t1
79c1 c279(c1 INT,
801 a80c2 CHAR(20));
812 b81ERROR 42S01: Table 't1' already exists
823 c82INSERT INTO t1 VALUES (1,'a'),(2,'b'),(3,'c');
83SELECT * FROM t2;83SELECT * FROM t1;
84ERROR 42S02: Table 'test.t2' doesn't exist84c1 c2
85DROP TABLE t1;851 a
86PREPARE stmt1 FROM 'SELECT 1';862 b
87EXECUTE stmt1;873 c
88188SELECT * FROM t2;
89189ERROR 42S02: Table 'test.t2' doesn't exist
90SHOW STATUS LIKE 'audit_log%';90DROP TABLE t1;
91Variable_name Value91PREPARE stmt1 FROM 'SELECT 1';
92DEALLOCATE PREPARE stmt1;92EXECUTE stmt1;
93show variables like 'audit_log%';931
94Variable_name Value941
95audit_log_buffer_size 409695SHOW STATUS LIKE 'audit_log%';
96audit_log_file test_audit.log96Variable_name Value
97audit_log_flush OFF97DEALLOCATE PREPARE stmt1;
98audit_log_format NEW98show variables like 'audit_log%';
99audit_log_policy LOGINS99Variable_name Value
100audit_log_rotate_on_size 0100audit_log_buffer_size 4096
101audit_log_rotations 0101audit_log_file test_audit.log
102audit_log_strategy SYNCHRONOUS102audit_log_flush OFF
103connect(localhost,no_such_user,,mysql,MASTER_PORT,MASTER_SOCKET);103audit_log_format NEW
104ERROR 28000: Access denied for user 'no_such_user'@'localhost' (using password: NO)104audit_log_policy LOGINS
105create table t1 (id int);105audit_log_rotate_on_size 0
106create table t2 (id int);106audit_log_rotations 0
107insert into t1 values (1), (2);107audit_log_strategy SEMISYNCHRONOUS
108insert into t2 values (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2);108connect(localhost,no_such_user,,mysql,MASTER_PORT,MASTER_SOCKET);
109select * from t1;109ERROR 28000: Access denied for user 'no_such_user'@'localhost' (using password: NO)
110id110create table t1 (id int);
1111111create table t2 (id int);
1122112insert into t1 values (1), (2);
113alter table t1 rename renamed_t1;113insert into t2 values (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2);
114select * from t_doesnt_exist;114select * from t1;
115ERROR 42S02: Table 'test.t_doesnt_exist' doesn't exist115id
116syntax_error_query;1161
117ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'syntax_error_query' at line 11172
118drop table renamed_t1, t2;118alter table t1 rename renamed_t1;
119show variables like 'audit_log%';119select * from t_doesnt_exist;
120Variable_name Value120ERROR 42S02: Table 'test.t_doesnt_exist' doesn't exist
121audit_log_buffer_size 4096121syntax_error_query;
122audit_log_file test_audit.log122ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'syntax_error_query' at line 1
123audit_log_flush OFF123drop table renamed_t1, t2;
124audit_log_format NEW124show variables like 'audit_log%';
125audit_log_policy LOGINS125Variable_name Value
126audit_log_rotate_on_size 0126audit_log_buffer_size 4096
127audit_log_rotations 0127audit_log_file test_audit.log
128audit_log_strategy SYNCHRONOUS128audit_log_flush OFF
129create database sa_db;129audit_log_format NEW
130create table t1 (id2 int);130audit_log_policy LOGINS
131insert into t1 values (1), (2);131audit_log_rotate_on_size 0
132select * from t1;132audit_log_rotations 0
133id2133audit_log_strategy SEMISYNCHRONOUS
1341134create database sa_db;
1352135create table t1 (id2 int);
136drop table t1;136insert into t1 values (1), (2);
137use sa_db;137select * from t1;
138create table sa_t1(id int);138id2
139insert into sa_t1 values (1), (2);1391
140drop table sa_t1;1402
141drop database sa_db;141drop table t1;
142create user 'jeffrey'@'localhost' IDENTIFIED BY 'mypass';142use sa_db;
143drop user 'jeffrey'@'localhost';143create table sa_t1(id int);
144select '&;&&&""""<><<>>>>';144insert into sa_t1 values (1), (2);
145&;&&&""""<><<>>>>145drop table sa_t1;
146&;&&&""""<><<>>>>146drop database sa_db;
147create user 'jeffrey'@'localhost' IDENTIFIED BY 'mypass';
148drop user 'jeffrey'@'localhost';
149select '&;&&&""""<><<>>>>';
150&;&&&""""<><<>>>>
151&;&&&""""<><<>>>>
152set global audit_log_flush= ON;
153CREATE TABLE t1 (c1 INT, c2 CHAR(20));
154CREATE TABLE t1
155(c1 INT,
156c2 CHAR(20));
157ERROR 42S01: Table 't1' already exists
158INSERT INTO t1 VALUES (1,'a'),(2,'b'),(3,'c');
159SELECT * FROM t1;
160c1 c2
1611 a
1622 b
1633 c
164SELECT * FROM t2;
165ERROR 42S02: Table 'test.t2' doesn't exist
166DROP TABLE t1;
167PREPARE stmt1 FROM 'SELECT 1';
168EXECUTE stmt1;
1691
1701
171SHOW STATUS LIKE 'audit_log%';
172Variable_name Value
173DEALLOCATE PREPARE stmt1;
174show variables like 'audit_log%';
175Variable_name Value
176audit_log_buffer_size 4096
177audit_log_file test_audit.log
178audit_log_flush OFF
179audit_log_format JSON
180audit_log_policy ALL
181audit_log_rotate_on_size 0
182audit_log_rotations 0
183audit_log_strategy SEMISYNCHRONOUS
184connect(localhost,no_such_user,,mysql,MASTER_PORT,MASTER_SOCKET);
185ERROR 28000: Access denied for user 'no_such_user'@'localhost' (using password: NO)
186create table t1 (id int);
187create table t2 (id int);
188insert into t1 values (1), (2);
189insert into t2 values (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2);
190select * from t1;
191id
1921
1932
194alter table t1 rename renamed_t1;
195select * from t_doesnt_exist;
196ERROR 42S02: Table 'test.t_doesnt_exist' doesn't exist
197syntax_error_query;
198ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'syntax_error_query' at line 1
199drop table renamed_t1, t2;
200show variables like 'audit_log%';
201Variable_name Value
202audit_log_buffer_size 4096
203audit_log_file test_audit.log
204audit_log_flush OFF
205audit_log_format JSON
206audit_log_policy ALL
207audit_log_rotate_on_size 0
208audit_log_rotations 0
209audit_log_strategy SEMISYNCHRONOUS
210create database sa_db;
211create table t1 (id2 int);
212insert into t1 values (1), (2);
213select * from t1;
214id2
2151
2162
217drop table t1;
218use sa_db;
219create table sa_t1(id int);
220insert into sa_t1 values (1), (2);
221drop table sa_t1;
222drop database sa_db;
223create user 'jeffrey'@'localhost' IDENTIFIED BY 'mypass';
224drop user 'jeffrey'@'localhost';
225select '&;&&&""""<><<>>>>';
226&;&&&""""<><<>>>>
227&;&&&""""<><<>>>>
228set global audit_log_flush= ON;
229CREATE TABLE t1 (c1 INT, c2 CHAR(20));
230CREATE TABLE t1
231(c1 INT,
232c2 CHAR(20));
233ERROR 42S01: Table 't1' already exists
234INSERT INTO t1 VALUES (1,'a'),(2,'b'),(3,'c');
235SELECT * FROM t1;
236c1 c2
2371 a
2382 b
2393 c
240SELECT * FROM t2;
241ERROR 42S02: Table 'test.t2' doesn't exist
242DROP TABLE t1;
243PREPARE stmt1 FROM 'SELECT 1';
244EXECUTE stmt1;
2451
2461
247SHOW STATUS LIKE 'audit_log%';
248Variable_name Value
249DEALLOCATE PREPARE stmt1;
250show variables like 'audit_log%';
251Variable_name Value
252audit_log_buffer_size 4096
253audit_log_file test_audit.log
254audit_log_flush OFF
255audit_log_format CSV
256audit_log_policy ALL
257audit_log_rotate_on_size 0
258audit_log_rotations 0
259audit_log_strategy SEMISYNCHRONOUS
260connect(localhost,no_such_user,,mysql,MASTER_PORT,MASTER_SOCKET);
261ERROR 28000: Access denied for user 'no_such_user'@'localhost' (using password: NO)
262create table t1 (id int);
263create table t2 (id int);
264insert into t1 values (1), (2);
265insert into t2 values (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2), (1), (2);
266select * from t1;
267id
2681
2692
270alter table t1 rename renamed_t1;
271select * from t_doesnt_exist;
272ERROR 42S02: Table 'test.t_doesnt_exist' doesn't exist
273syntax_error_query;
274ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'syntax_error_query' at line 1
275drop table renamed_t1, t2;
276show variables like 'audit_log%';
277Variable_name Value
278audit_log_buffer_size 4096
279audit_log_file test_audit.log
280audit_log_flush OFF
281audit_log_format CSV
282audit_log_policy ALL
283audit_log_rotate_on_size 0
284audit_log_rotations 0
285audit_log_strategy SEMISYNCHRONOUS
286create database sa_db;
287create table t1 (id2 int);
288insert into t1 values (1), (2);
289select * from t1;
290id2
2911
2922
293drop table t1;
294use sa_db;
295create table sa_t1(id int);
296insert into sa_t1 values (1), (2);
297drop table sa_t1;
298drop database sa_db;
299create user 'jeffrey'@'localhost' IDENTIFIED BY 'mypass';
300drop user 'jeffrey'@'localhost';
301select '&;&&&""""<><<>>>>';
302&;&&&""""<><<>>>>
303&;&&&""""<><<>>>>
304set global audit_log_flush= ON;
147305
=== modified file 'mysql-test/t/audit_log.test'
--- mysql-test/t/audit_log.test 2014-04-21 12:07:45 +0000
+++ mysql-test/t/audit_log.test 2014-05-26 07:58:11 +0000
@@ -1,23 +1,77 @@
1--source include/not_embedded.inc1--source include/not_embedded.inc
22
3# Adjustment to the OS dependent extension of shared libraries.3let $MYSQLD_DATADIR= `select @@datadir`;
4let $expected_extension= so;4let MYSQLD_DATADIR= $MYSQLD_DATADIR;
5if(`SELECT CONVERT(@@version_compile_os USING latin1)5
6 IN ("Win32","Win64","Windows")`)6--source include/audit_log_events.inc
7{7
8 let $expected_extension= dll;8--move_file $MYSQLD_DATADIR/test_audit.log $MYSQLD_DATADIR/test_audit_old.log
9}9set global audit_log_flush= ON;
1010perl;
11let $MYSQL_DATA_DIR= `select @@datadir`;11 eval "use XML::Parser; 1" or exit 0;
1212 $p = new XML::Parser;
13--source include/audit_log_events.inc13 $p->parsefile($ENV{'MYSQLD_DATADIR'} . '/test_audit_old.log');
1414EOF
15--exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect15--remove_file $MYSQLD_DATADIR/test_audit.log
16--shutdown_server16
17--source include/wait_until_disconnected.inc17--exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
18--enable_reconnect18--shutdown_server
19--exec echo "restart: --audit_log_policy=LOGINS --audit-log-format=NEW --audit_log_strategy=SYNCHRONOUS" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect19--source include/wait_until_disconnected.inc
20--source include/wait_until_connected_again.inc20--enable_reconnect
2121--exec echo "restart: --audit_log_policy=LOGINS --audit-log-format=NEW --audit_log_strategy=SEMISYNCHRONOUS" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
22--source include/audit_log_events.inc22--source include/wait_until_connected_again.inc
2323
24--source include/audit_log_events.inc
25
26--move_file $MYSQLD_DATADIR/test_audit.log $MYSQLD_DATADIR/test_audit_new.log
27set global audit_log_flush= ON;
28perl;
29 eval "use XML::Parser; 1" or exit 0;
30 $p = new XML::Parser;
31 $p->parsefile($ENV{'MYSQLD_DATADIR'} . '/test_audit_new.log');
32EOF
33--remove_file $MYSQLD_DATADIR/test_audit.log
34
35--exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
36--shutdown_server
37--source include/wait_until_disconnected.inc
38--enable_reconnect
39--exec echo "restart: --audit-log-format=JSON --audit_log_strategy=SEMISYNCHRONOUS" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
40--source include/wait_until_connected_again.inc
41
42--source include/audit_log_events.inc
43
44--move_file $MYSQLD_DATADIR/test_audit.log $MYSQLD_DATADIR/test_audit_json.log
45set global audit_log_flush= ON;
46perl;
47 eval "use JSON qw(decode_json); 1" or exit 0;
48 open my $file, $ENV{'MYSQLD_DATADIR'} . '/test_audit_json.log' or die "Could not open log: $!";
49 while (my $line = <$file>) {
50 decode_json($line);
51 }
52 close $file;
53EOF
54--remove_file $MYSQLD_DATADIR/test_audit.log
55
56--exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
57--shutdown_server
58--source include/wait_until_disconnected.inc
59--enable_reconnect
60--exec echo "restart: --audit-log-format=CSV --audit_log_strategy=SEMISYNCHRONOUS" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
61--source include/wait_until_connected_again.inc
62
63--source include/audit_log_events.inc
64
65--move_file $MYSQLD_DATADIR/test_audit.log $MYSQLD_DATADIR/test_audit_csv.log
66set global audit_log_flush= ON;
67perl;
68 eval "use Text::CSV; 1" or exit 0;
69 my $p = Text::CSV->new({ binary => 1, auto_diag => 1, sep_char => ',' });
70 open my $file, $ENV{'MYSQLD_DATADIR'} . '/test_audit_csv.log' or die "Could not open log: $!";
71 while ($p->getline($file)) {};
72 if (not $p->eof) {
73 die "CSV parse error " . $p->error_diag();
74 }
75 close $file;
76EOF
77--remove_file $MYSQLD_DATADIR/test_audit.log
2478
=== modified file 'plugin/audit_log/audit_log.c'
--- plugin/audit_log/audit_log.c 2014-05-14 14:32:33 +0000
+++ plugin/audit_log/audit_log.c 2014-05-26 07:58:11 +0000
@@ -35,7 +35,9 @@
35enum audit_log_policy_t { ALL, NONE, LOGINS, QUERIES };35enum audit_log_policy_t { ALL, NONE, LOGINS, QUERIES };
36enum audit_log_strategy_t36enum audit_log_strategy_t
37 { ASYNCHRONOUS, PERFORMANCE, SEMISYNCHRONOUS, SYNCHRONOUS };37 { ASYNCHRONOUS, PERFORMANCE, SEMISYNCHRONOUS, SYNCHRONOUS };
38enum audit_log_format_t { OLD, NEW };38enum audit_log_format_t { OLD, NEW, JSON, CSV };
39
40typedef void (*escape_buf_func_t)(const char *, size_t *, char *, size_t *);
3941
40static LOGGER_HANDLE *audit_file_logger= NULL;42static LOGGER_HANDLE *audit_file_logger= NULL;
41static audit_log_buffer_t *audit_log_buffer= NULL;43static audit_log_buffer_t *audit_log_buffer= NULL;
@@ -113,41 +115,37 @@
113 return buf;115 return buf;
114}116}
115117
118typedef struct
119{
120 char character;
121 size_t length;
122 const char *replacement;
123} escape_rule_t;
124
116static125static
117void xml_escape(const char *in, size_t *inlen, char* out, size_t *outlen)126void escape_buf(const char *in, size_t *inlen, char *out, size_t *outlen,
127 const escape_rule_t *escape_rules)
118{128{
119 char* outstart = out;129 char* outstart = out;
120 const char* base = in;130 const char* base = in;
121 char* outend = out + *outlen;131 char* outend = out + *outlen;
122 const char* inend;132 const char* inend;
123 size_t i;133 const escape_rule_t *rule;
124 my_bool replaced;134 my_bool replaced;
125135
126 const struct {
127 char symbol;
128 size_t length;
129 const char *replace;
130 } escape[] = {
131 { '<', 4, "&lt;" },
132 { '>', 4, "&gt;" },
133 { '&', 5, "&amp;" },
134 { '\r', 5, "&#13;" },
135 { '"', 6, "&quot;" },
136 };
137
138 inend = in + (*inlen);136 inend = in + (*inlen);
139137
140 while ((in < inend) && (out < outend))138 while ((in < inend) && (out < outend))
141 {139 {
142 replaced= FALSE;140 replaced= FALSE;
143 for (i= 0; i < array_elements(escape); i++)141 for (rule= escape_rules; rule->character; rule++)
144 {142 {
145 if (*in == escape[i].symbol)143 if (*in == rule->character)
146 {144 {
147 if ((outend - out) < (int) escape[i].length)145 if ((outend - out) < (int) rule->length)
148 goto end_of_buffer;146 goto end_of_buffer;
149 memcpy(out, escape[i].replace, escape[i].length);147 memcpy(out, rule->replacement, rule->length);
150 out += escape[i].length;148 out += rule->length;
151 replaced= TRUE;149 replaced= TRUE;
152 break;150 break;
153 }151 }
@@ -161,20 +159,71 @@
161 *inlen = in - base;159 *inlen = in - base;
162}160}
163161
164162static
165static163void xml_escape(const char *in, size_t *inlen, char *out, size_t *outlen)
166char *xml_escape_string(const char *in, size_t inlen,164{
167 char *out, size_t outlen)165 const escape_rule_t rules[]=
168{166 {
167 { '<', 4, "&lt;" },
168 { '>', 4, "&gt;" },
169 { '&', 5, "&amp;" },
170 { '\r', 5, "&#13;" },
171 { '\n', 5, "&#10;" },
172 { '"', 6, "&quot;" },
173 { 0, 0, NULL }
174 };
175
176 escape_buf(in, inlen, out, outlen, rules);
177}
178
179static
180void json_escape(const char *in, size_t *inlen, char *out, size_t *outlen)
181{
182 const escape_rule_t rules[]=
183 {
184 { '\\', 2, "\\\\" },
185 { '"', 2, "\\\"" },
186 { '\r', 2, "\\r" },
187 { '\n', 2, "\\n" },
188 { 0, 0, NULL }
189 };
190
191 escape_buf(in, inlen, out, outlen, rules);
192}
193
194static
195void csv_escape(const char *in, size_t *inlen, char *out, size_t *outlen)
196{
197 const escape_rule_t rules[]=
198 {
199 { '"', 2, "\"\"" },
200 { 0, 0, NULL }
201 };
202
203 escape_buf(in, inlen, out, outlen, rules);
204}
205
206static
207char *escape_string(const char *in, size_t inlen,
208 char *out, size_t outlen,
209 char **endptr)
210{
211 const escape_buf_func_t format_escape_func[]=
212 { xml_escape, xml_escape, json_escape, csv_escape };
213
169 if (in != NULL)214 if (in != NULL)
170 {215 {
171 --outlen;216 --outlen;
172 xml_escape(in, &inlen, out, &outlen);217 format_escape_func[audit_log_format](in, &inlen, out, &outlen);
173 out[outlen]= 0;218 out[outlen]= 0;
219 if (endptr)
220 *endptr= out + outlen + 1;
174 }221 }
175 else222 else
176 {223 {
177 out= 0;224 *out= 0;
225 if (endptr)
226 *endptr= out + 1;
178 }227 }
179 return out;228 return out;
180}229}
@@ -273,13 +322,14 @@
273 char arg_buf[512];322 char arg_buf[512];
274 const char *format_string[] = {323 const char *format_string[] = {
275 "<AUDIT_RECORD\n"324 "<AUDIT_RECORD\n"
276 " \"NAME\"=\"%s\"\n"325 " NAME=\"%s\"\n"
277 " \"RECORD\"=\"%s\"\n"326 " RECORD=\"%s\"\n"
278 " \"TIMESTAMP\"=\"%s\"\n"327 " TIMESTAMP=\"%s\"\n"
279 " \"MYSQL_VERSION\"=\"%s\"\n"328 " MYSQL_VERSION=\"%s\"\n"
280 " \"STARTUP_OPTIONS\"=\"%s\"\n"329 " STARTUP_OPTIONS=\"%s\"\n"
281 " \"OS_VERSION\"=\""MACHINE_TYPE"-"SYSTEM_TYPE"\",\n"330 " OS_VERSION=\""MACHINE_TYPE"-"SYSTEM_TYPE"\"\n"
282 "/>\n",331 "/>\n",
332
283 "<AUDIT_RECORD>\n"333 "<AUDIT_RECORD>\n"
284 " <NAME>%s</NAME>\n"334 " <NAME>%s</NAME>\n"
285 " <RECORD>%s</RECORD>\n"335 " <RECORD>%s</RECORD>\n"
@@ -287,7 +337,15 @@
287 " <MYSQL_VERSION>%s</MYSQL_VERSION>\n"337 " <MYSQL_VERSION>%s</MYSQL_VERSION>\n"
288 " <STARTUP_OPTIONS>%s</STARTUP_OPTIONS>\n"338 " <STARTUP_OPTIONS>%s</STARTUP_OPTIONS>\n"
289 " <OS_VERSION>"MACHINE_TYPE"-"SYSTEM_TYPE"</OS_VERSION>\n"339 " <OS_VERSION>"MACHINE_TYPE"-"SYSTEM_TYPE"</OS_VERSION>\n"
290 "</AUDIT_RECORD>\n" };340 "</AUDIT_RECORD>\n",
341
342 "{\"audit_record\":{\"name\":\"%s\",\"record\":\"%s\","
343 "\"timestamp\":\"%s\",\"mysql_version\":\"%s\","
344 "\"startup_optionsi\":\"%s\","
345 "\"os_version\":\""MACHINE_TYPE"-"SYSTEM_TYPE"\"}}\n",
346
347 "\"%s\",\"%s\",\"%s\",\"%s\",\"%s\","
348 "\""MACHINE_TYPE"-"SYSTEM_TYPE"\"\n" };
291349
292 return my_snprintf(buf, buflen,350 return my_snprintf(buf, buflen,
293 format_string[audit_log_format],351 format_string[audit_log_format],
@@ -307,21 +365,23 @@
307{365{
308 char id_str[MAX_RECORD_ID_SIZE];366 char id_str[MAX_RECORD_ID_SIZE];
309 char timestamp[MAX_TIMESTAMP_SIZE];367 char timestamp[MAX_TIMESTAMP_SIZE];
310 char query[512];368 char query[512], tmp[128];
369 char *endptr= tmp, *endtmp= tmp + sizeof(tmp);
311 const char *format_string[] = {370 const char *format_string[] = {
312 "<AUDIT_RECORD\n"371 "<AUDIT_RECORD\n"
313 " \"NAME\"=\"%s\"\n"372 " NAME=\"%s\"\n"
314 " \"RECORD\"=\"%s\"\n"373 " RECORD=\"%s\"\n"
315 " \"TIMESTAMP\"=\"%s\"\n"374 " TIMESTAMP=\"%s\"\n"
316 " \"COMMAND_CLASS\"=\"%s\"\n"375 " COMMAND_CLASS=\"%s\"\n"
317 " \"CONNECTION_ID\"=\"%lu\"\n"376 " CONNECTION_ID=\"%lu\"\n"
318 " \"STATUS\"=\"%d\"\n"377 " STATUS=\"%d\"\n"
319 " \"SQLTEXT\"=\"%s\"\n"378 " SQLTEXT=\"%s\"\n"
320 " \"USER\"=\"%s\"\n"379 " USER=\"%s\"\n"
321 " \"HOST\"=\"%s\"\n"380 " HOST=\"%s\"\n"
322 " \"OS_USER\"=\"%s\"\n"381 " OS_USER=\"%s\"\n"
323 " \"IP\"=\"%s\"\n"382 " IP=\"%s\"\n"
324 "/>\n",383 "/>\n",
384
325 "<AUDIT_RECORD>\n"385 "<AUDIT_RECORD>\n"
326 " <NAME>%s</NAME>\n"386 " <NAME>%s</NAME>\n"
327 " <RECORD>%s</RECORD>\n"387 " <RECORD>%s</RECORD>\n"
@@ -334,7 +394,23 @@
334 " <HOST>%s</HOST>\n"394 " <HOST>%s</HOST>\n"
335 " <OS_USER>%s</OS_USER>\n"395 " <OS_USER>%s</OS_USER>\n"
336 " <IP>%s</IP>\n"396 " <IP>%s</IP>\n"
337 "</AUDIT_RECORD>\n" };397 "</AUDIT_RECORD>\n",
398
399 "{\"audit_record\":"
400 "{\"name\":\"%s\","
401 "\"record\":\"%s\","
402 "\"timestamp\":\"%s\","
403 "\"command_class\":\"%s\","
404 "\"connection_id\":\"%lu\","
405 "\"status\":%d,"
406 "\"sqltext\":\"%s\","
407 "\"user\":\"%s\","
408 "\"host\":\"%s\","
409 "\"os_user\":\"%s\","
410 "\"ip\":\"%s\"}}\n",
411
412 "\"%s\",\"%s\",\"%s\",\"%s\",\"%lu\",%d,\"%s\",\"%s\","
413 "\"%s\",\"%s\",\"%s\"\n" };
338414
339 return my_snprintf(buf, buflen,415 return my_snprintf(buf, buflen,
340 format_string[audit_log_format],416 format_string[audit_log_format],
@@ -343,13 +419,21 @@
343 make_timestamp(timestamp, sizeof(timestamp), t),419 make_timestamp(timestamp, sizeof(timestamp), t),
344 event->general_sql_command.str,420 event->general_sql_command.str,
345 event->general_thread_id, status,421 event->general_thread_id, status,
346 xml_escape_string(event->general_query,422 escape_string(event->general_query,
347 event->general_query_length,423 event->general_query_length,
348 query, sizeof(query)),424 query, sizeof(query), NULL),
349 event->general_user,425 escape_string(event->general_user,
350 event->general_host.str,426 event->general_user_length,
351 event->general_external_user.str,427 endptr, endtmp - endptr, &endptr),
352 event->general_ip.str);428 escape_string(event->general_host.str,
429 event->general_host.length,
430 endptr, endtmp - endptr, &endptr),
431 escape_string(event->general_external_user.str,
432 event->general_external_user.length,
433 endptr, endtmp - endptr, &endptr),
434 escape_string(event->general_ip.str,
435 event->general_ip.length,
436 endptr, endtmp - endptr, &endptr));
353}437}
354438
355static439static
@@ -359,21 +443,24 @@
359{443{
360 char id_str[MAX_RECORD_ID_SIZE];444 char id_str[MAX_RECORD_ID_SIZE];
361 char timestamp[MAX_TIMESTAMP_SIZE];445 char timestamp[MAX_TIMESTAMP_SIZE];
446 char tmp[128];
447 char *endptr= tmp, *endtmp= tmp + sizeof(tmp);
362 const char *format_string[] = {448 const char *format_string[] = {
363 "<AUDIT_RECORD\n"449 "<AUDIT_RECORD\n"
364 " \"NAME\"=\"%s\"\n"450 " NAME=\"%s\"\n"
365 " \"RECORD\"=\"%s\"\n"451 " RECORD=\"%s\"\n"
366 " \"TIMESTAMP\"=\"%s\"\n"452 " TIMESTAMP=\"%s\"\n"
367 " \"CONNECTION_ID\"=\"%lu\"\n"453 " CONNECTION_ID=\"%lu\"\n"
368 " \"STATUS\"=\"%d\"\n"454 " STATUS=\"%d\"\n"
369 " \"USER\"=\"%s\"\n"455 " USER=\"%s\"\n"
370 " \"PRIV_USER\"=\"%s\"\n"456 " PRIV_USER=\"%s\"\n"
371 " \"OS_LOGIN\"=\"%s\"\n"457 " OS_LOGIN=\"%s\"\n"
372 " \"PROXY_USER\"=\"%s\"\n"458 " PROXY_USER=\"%s\"\n"
373 " \"HOST\"=\"%s\"\n"459 " HOST=\"%s\"\n"
374 " \"IP\"=\"%s\"\n"460 " IP=\"%s\"\n"
375 " \"DB\"=\"%s\"\n"461 " DB=\"%s\"\n"
376 "/>\n",462 "/>\n",
463
377 "<AUDIT_RECORD>\n"464 "<AUDIT_RECORD>\n"
378 " <NAME>%s</NAME>\n"465 " <NAME>%s</NAME>\n"
379 " <RECORD>%s</RECORD>\n"466 " <RECORD>%s</RECORD>\n"
@@ -387,34 +474,96 @@
387 " <HOST>%s</HOST>\n"474 " <HOST>%s</HOST>\n"
388 " <IP>%s</IP>\n"475 " <IP>%s</IP>\n"
389 " <DB>%s</DB>\n"476 " <DB>%s</DB>\n"
390 "</AUDIT_RECORD>\n" };477 "</AUDIT_RECORD>\n",
478
479 "{\"audit_record\":"
480 "{\"name\":\"%s\","
481 "\"record\":\"%s\","
482 "\"timestamp\":\"%s\","
483 "\"connection_id\":\"%lu\","
484 "\"status\":%d,"
485 "\"user\":\"%s\","
486 "\"priv_user\":\"%s\","
487 "\"os_login\":\"%s\","
488 "\"proxy_user\":\"%s\","
489 "\"host\":\"%s\","
490 "\"ip\":\"%s\","
491 "\"db\":\"%s\"}}\n",
492
493 "\"%s\",\"%s\",\"%s\",\"%lu\",%d,\"%s\",\"%s\",\"%s\","
494 "\"%s\",\"%s\",\"%s\",\"%s\"\n" };
391495
392 return my_snprintf(buf, buflen,496 return my_snprintf(buf, buflen,
393 format_string[audit_log_format],497 format_string[audit_log_format],
394 name,498 name,
395 make_record_id(id_str, sizeof(id_str)),499 make_record_id(id_str, sizeof(id_str)),
396 make_timestamp(timestamp, sizeof(timestamp), t),500 make_timestamp(timestamp, sizeof(timestamp), t),
397 event->thread_id,501 event->thread_id,
398 event->status,502 event->status,
399 event->user ? event->user : "",503 escape_string(event->user,
400 event->priv_user ? event->priv_user : "",504 event->user_length,
401 event->external_user ? event->external_user : "",505 endptr, endtmp - endptr, &endptr),
402 event->proxy_user ? event->proxy_user : "",506 escape_string(event->priv_user,
403 event->host ? event->host : "",507 event->priv_user_length,
404 event->ip ? event->ip : "",508 endptr, endtmp - endptr, &endptr),
405 event->database ? event->database : "");509 escape_string(event->external_user,
406}510 event->external_user_length,
407511 endptr, endtmp - endptr, &endptr),
512 escape_string(event->proxy_user,
513 event->proxy_user_length,
514 endptr, endtmp - endptr, &endptr),
515 escape_string(event->host,
516 event->host_length,
517 endptr, endtmp - endptr, &endptr),
518 escape_string(event->user,
519 event->user_length,
520 endptr, endtmp - endptr, &endptr),
521 escape_string(event->ip,
522 event->ip_length,
523 endptr, endtmp - endptr, &endptr),
524 escape_string(event->database,
525 event->database_length,
526 endptr, endtmp - endptr, &endptr));
527}
528
529static
530size_t audit_log_header(MY_STAT *stat, char *buf, size_t buflen)
531{
532 const char *format_string[] = {
533 "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
534 "<AUDIT>\n",
535 "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
536 "<AUDIT>\n",
537 "",
538 "" };
539
540 log_file_time= stat->st_mtime;
541
542 init_record_id(stat->st_size);
543
544 return my_snprintf(buf, buflen, format_string[audit_log_format]);
545}
546
547
548static
549size_t audit_log_footer(char *buf, size_t buflen)
550{
551 const char *format_string[] = {
552 "</AUDIT>\n",
553 "</AUDIT>\n",
554 "",
555 "" };
556
557 return my_snprintf(buf, buflen, format_string[audit_log_format]);
558}
408559
409static560static
410int init_new_log_file()561int init_new_log_file()
411{562{
412 MY_STAT stat_arg;
413
414 audit_file_logger= logger_open(audit_log_file, audit_log_rotate_on_size,563 audit_file_logger= logger_open(audit_log_file, audit_log_rotate_on_size,
415 audit_log_rotate_on_size ? audit_log_rotations : 0,564 audit_log_rotate_on_size ? audit_log_rotations : 0,
416 audit_log_strategy >= SEMISYNCHRONOUS,565 audit_log_strategy >= SEMISYNCHRONOUS,
417 &stat_arg);566 audit_log_header);
418 if (audit_file_logger == NULL)567 if (audit_file_logger == NULL)
419 {568 {
420 fprintf_timestamp(stderr);569 fprintf_timestamp(stderr);
@@ -423,10 +572,6 @@
423 return(1);572 return(1);
424 }573 }
425574
426 log_file_time= stat_arg.st_mtime;
427
428 init_record_id(stat_arg.st_size);
429
430 return(0);575 return(0);
431}576}
432577
@@ -434,9 +579,7 @@
434static579static
435int reopen_log_file()580int reopen_log_file()
436{581{
437 MY_STAT stat_arg;582 if (logger_reopen(audit_file_logger, audit_log_header, audit_log_footer))
438
439 if (logger_reopen(audit_file_logger, &stat_arg))
440 {583 {
441 fprintf_timestamp(stderr);584 fprintf_timestamp(stderr);
442 fprintf(stderr, "Cannot open file %s. ", audit_log_file);585 fprintf(stderr, "Cannot open file %s. ", audit_log_file);
@@ -444,10 +587,6 @@
444 return(1);587 return(1);
445 }588 }
446589
447 log_file_time= stat_arg.st_mtime;
448
449 init_record_id(stat_arg.st_size);
450
451 return(0);590 return(0);
452}591}
453592
@@ -456,7 +595,7 @@
456void close_log_file()595void close_log_file()
457{596{
458 if (audit_file_logger != NULL)597 if (audit_file_logger != NULL)
459 logger_close(audit_file_logger);598 logger_close(audit_file_logger, audit_log_footer);
460}599}
461600
462601
@@ -466,6 +605,8 @@
466 char buf[1024];605 char buf[1024];
467 size_t len;606 size_t len;
468607
608 logger_init_mutexes();
609
469 if (init_new_log_file())610 if (init_new_log_file())
470 return(1);611 return(1);
471612
@@ -494,7 +635,6 @@
494635
495 if (audit_log_buffer != NULL)636 if (audit_log_buffer != NULL)
496 audit_log_buffer_shutdown(audit_log_buffer);637 audit_log_buffer_shutdown(audit_log_buffer);
497
498 close_log_file();638 close_log_file();
499639
500 return(0);640 return(0);
@@ -612,7 +752,7 @@
612 ASYNCHRONOUS, &audit_log_strategy_typelib);752 ASYNCHRONOUS, &audit_log_strategy_typelib);
613753
614static const char *audit_log_format_names[]=754static const char *audit_log_format_names[]=
615 { "OLD", "NEW", 0 };755 { "OLD", "NEW", "JSON", "CSV", 0 };
616static TYPELIB audit_log_format_typelib=756static TYPELIB audit_log_format_typelib=
617{757{
618 array_elements(audit_log_format_names) - 1, "audit_log_format_typelib",758 array_elements(audit_log_format_names) - 1, "audit_log_format_typelib",
@@ -674,7 +814,7 @@
674{814{
675 char new_val= *(const char *)(save);815 char new_val= *(const char *)(save);
676816
677 if (new_val != audit_log_flush && new_val == TRUE)817 if (new_val != audit_log_flush && new_val)
678 {818 {
679 audit_log_flush= TRUE;819 audit_log_flush= TRUE;
680 reopen_log_file();820 reopen_log_file();
681821
=== modified file 'plugin/audit_log/file_logger.c'
--- plugin/audit_log/file_logger.c 2014-04-21 12:07:45 +0000
+++ plugin/audit_log/file_logger.c 2014-05-26 07:58:11 +0000
@@ -13,12 +13,11 @@
13 along with this program; if not, write to the Free Software13 along with this program; if not, write to the Free Software
14 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */14 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
1515
16#include <string.h>16#include <my_global.h>
17
18#include <mysql/plugin.h>17#include <mysql/plugin.h>
19#include <my_global.h>
20#include <my_sys.h>18#include <my_sys.h>
21#include <my_pthread.h>19#include <my_pthread.h>
20#include <string.h>
2221
23#include "logger.h"22#include "logger.h"
2423
@@ -85,14 +84,17 @@
85 return (i == 0) ? 0 : ((i < 10) ? 1 : ((i < 100) ? 2 : 3));84 return (i == 0) ? 0 : ((i < 10) ? 1 : ((i < 100) ? 2 : 3));
86}85}
8786
88
89LOGGER_HANDLE *logger_open(const char *path,87LOGGER_HANDLE *logger_open(const char *path,
90 unsigned long long size_limit,88 unsigned long long size_limit,
91 unsigned int rotations,89 unsigned int rotations,
92 int thread_safe,90 int thread_safe,
93 MY_STAT *stat)91 logger_prolog_func_t header)
94{92{
95 LOGGER_HANDLE new_log, *l_perm;93 LOGGER_HANDLE new_log, *l_perm;
94 MY_STAT stat_arg;
95 char buf[128];
96 size_t len;
97
96 /*98 /*
97 I don't think we ever need more rotations,99 I don't think we ever need more rotations,
98 but if it's so, the rotation procedure should be adapted to it.100 but if it's so, the rotation procedure should be adapted to it.
@@ -113,22 +115,19 @@
113 return 0;115 return 0;
114 }116 }
115117
116 if ((new_log.file= open(new_log.path, LOG_FLAGS, 0666)) < 0)118 if ((new_log.file= my_open(new_log.path, LOG_FLAGS, 0666)) < 0)
117 {119 {
118 errno= my_errno;120 errno= my_errno;
119 /* Check errno for the cause */121 /* Check errno for the cause */
120 return 0;122 return 0;
121 }123 }
122124
123 if (stat != NULL)125 if (my_fstat(new_log.file, &stat_arg, MYF(0)))
124 {126 {
125 if (my_fstat(new_log.file, stat, MYF(0)))127 errno= my_errno;
126 {128 my_close(new_log.file, MYF(0));
127 errno= my_errno;129 new_log.file= -1;
128 my_close(new_log.file, MYF(0));130 return 0;
129 new_log.file= -1;
130 return 0;
131 }
132 }131 }
133132
134 if (!(l_perm= (LOGGER_HANDLE *) my_malloc(sizeof(LOGGER_HANDLE), MYF(0))))133 if (!(l_perm= (LOGGER_HANDLE *) my_malloc(sizeof(LOGGER_HANDLE), MYF(0))))
@@ -139,22 +138,25 @@
139 }138 }
140 *l_perm= new_log;139 *l_perm= new_log;
141140
142#if defined(HAVE_PSI_INTERFACE) && !defined(FLOGGER_NO_PSI) && !defined(FLOGGER_NO_THREADSAFE)
143 if (PSI_server)
144 PSI_server->register_mutex("file_logger",
145 mutex_list, array_elements(mutex_list));
146#endif /*HAVE_PSI_INTERFACE && !FLOGGER_NO_PSI*/
147
148 flogger_mutex_init(key_LOCK_logger_service, l_perm,141 flogger_mutex_init(key_LOCK_logger_service, l_perm,
149 MY_MUTEX_INIT_FAST);142 MY_MUTEX_INIT_FAST);
150143
144 len= header(&stat_arg, buf, sizeof(buf));
145 my_write(l_perm->file, (uchar *)buf, len, MYF(0));
146
151 return l_perm;147 return l_perm;
152}148}
153149
154int logger_close(LOGGER_HANDLE *log)150int logger_close(LOGGER_HANDLE *log, logger_epilog_func_t footer)
155{151{
156 int result;152 int result;
157 File file= log->file;153 File file= log->file;
154 char buf[128];
155 size_t len;
156
157 len= footer(buf, sizeof(buf));
158 my_write(file, (uchar *)buf, len, MYF(0));
159
158 flogger_mutex_destroy(log);160 flogger_mutex_destroy(log);
159 my_free(log);161 my_free(log);
160 if ((result= my_close(file, MYF(0))))162 if ((result= my_close(file, MYF(0))))
@@ -163,12 +165,19 @@
163}165}
164166
165167
166int logger_reopen(LOGGER_HANDLE *log, MY_STAT *stat)168int logger_reopen(LOGGER_HANDLE *log, logger_prolog_func_t header,
169 logger_epilog_func_t footer)
167{170{
168 int result= 0;171 int result= 0;
172 MY_STAT stat_arg;
173 char buf[128];
174 size_t len;
169175
170 flogger_mutex_lock(log);176 flogger_mutex_lock(log);
171177
178 len= footer(buf, sizeof(buf));
179 my_write(log->file, (uchar *)buf, len, MYF(0));
180
172 if ((result= my_close(log->file, MYF(0))))181 if ((result= my_close(log->file, MYF(0))))
173 {182 {
174 errno= my_errno;183 errno= my_errno;
@@ -182,19 +191,19 @@
182 goto error;191 goto error;
183 }192 }
184193
185 if (stat != NULL)194 if ((result= my_fstat(log->file, &stat_arg, MYF(0))))
186 {195 {
187 if ((result= my_fstat(log->file, stat, MYF(0))))196 errno= my_errno;
188 {197 goto error;
189 errno= my_errno;
190 goto error;
191 }
192 }198 }
193199
200 len= header(&stat_arg, buf, sizeof(buf));
201 my_write(log->file, (uchar *)buf, len, MYF(0));
202
194error:203error:
195 flogger_mutex_unlock(log);204 flogger_mutex_unlock(log);
196205
197 return 0;206 return result;
198}207}
199208
200209
201210
=== modified file 'plugin/audit_log/logger.h'
--- plugin/audit_log/logger.h 2014-04-21 12:07:45 +0000
+++ plugin/audit_log/logger.h 2014-05-26 07:58:11 +0000
@@ -60,20 +60,23 @@
60#endif60#endif
6161
62typedef struct logger_handle_st LOGGER_HANDLE;62typedef struct logger_handle_st LOGGER_HANDLE;
63typedef size_t (logger_prolog_func_t)(MY_STAT *, char *buf, size_t buflen);
64typedef size_t (logger_epilog_func_t)(char *buf, size_t buflen);
6365
64void logger_init_mutexes();66void logger_init_mutexes();
65LOGGER_HANDLE *logger_open(const char *path,67LOGGER_HANDLE *logger_open(const char *path,
66 unsigned long long size_limit,68 unsigned long long size_limit,
67 unsigned int rotations,69 unsigned int rotations,
68 int thread_safe,70 int thread_safe,
69 MY_STAT *stat);71 logger_prolog_func_t header);
70int logger_close(LOGGER_HANDLE *log);72int logger_close(LOGGER_HANDLE *log, logger_epilog_func_t footer);
71int logger_vprintf(LOGGER_HANDLE *log, const char *fmt, va_list argptr);73int logger_vprintf(LOGGER_HANDLE *log, const char *fmt, va_list argptr);
72int logger_printf(LOGGER_HANDLE *log, const char *fmt, ...);74int logger_printf(LOGGER_HANDLE *log, const char *fmt, ...);
73int logger_write(LOGGER_HANDLE *log, const char *buffer, size_t size);75int logger_write(LOGGER_HANDLE *log, const char *buffer, size_t size);
74int logger_rotate(LOGGER_HANDLE *log); 76int logger_rotate(LOGGER_HANDLE *log);
75int logger_sync(LOGGER_HANDLE *log);77int logger_sync(LOGGER_HANDLE *log);
76int logger_reopen(LOGGER_HANDLE *log, MY_STAT *stat);78int logger_reopen(LOGGER_HANDLE *log, logger_prolog_func_t header,
79 logger_epilog_func_t footer);
77void logger_set_size_limit(LOGGER_HANDLE *log, unsigned long long size_limit);80void logger_set_size_limit(LOGGER_HANDLE *log, unsigned long long size_limit);
78void logger_set_rotations(LOGGER_HANDLE *log, unsigned int rotations);81void logger_set_rotations(LOGGER_HANDLE *log, unsigned int rotations);
7982

Subscribers

People subscribed via source and target branches