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

Proposed by Sergei Glushchenko on 2014-05-26
Status: Merged
Approved by: Laurynas Biveinis on 2014-07-15
Approved revision: 648
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) 2014-05-26 Approve on 2014-07-15
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.
Laurynas Biveinis (laurynas-biveinis) wrote : Posted in a previous version of this proposal

Wrong target branch?

review: Resubmit

Yes, it was wrong branch.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'mysql-test/include/audit_log_events.inc'
2--- mysql-test/include/audit_log_events.inc 2014-05-14 14:32:33 +0000
3+++ mysql-test/include/audit_log_events.inc 2014-05-26 07:58:11 +0000
4@@ -2,7 +2,9 @@
5
6 CREATE TABLE t1 (c1 INT, c2 CHAR(20));
7 --error ER_TABLE_EXISTS_ERROR
8-CREATE TABLE t1 (c1 INT, c2 CHAR(20));
9+CREATE TABLE t1
10+ (c1 INT,
11+ c2 CHAR(20));
12 INSERT INTO t1 VALUES (1,'a'),(2,'b'),(3,'c');
13 SELECT * FROM t1;
14 --error ER_NO_SUCH_TABLE
15
16=== modified file 'mysql-test/r/audit_log.result'
17--- mysql-test/r/audit_log.result 2014-05-14 14:32:33 +0000
18+++ mysql-test/r/audit_log.result 2014-05-26 07:58:11 +0000
19@@ -1,146 +1,304 @@
20 CREATE TABLE t1 (c1 INT, c2 CHAR(20));
21-CREATE TABLE t1 (c1 INT, c2 CHAR(20));
22-ERROR 42S01: Table 't1' already exists
23-INSERT INTO t1 VALUES (1,'a'),(2,'b'),(3,'c');
24-SELECT * FROM t1;
25-c1 c2
26-1 a
27-2 b
28-3 c
29-SELECT * FROM t2;
30-ERROR 42S02: Table 'test.t2' doesn't exist
31-DROP TABLE t1;
32-PREPARE stmt1 FROM 'SELECT 1';
33-EXECUTE stmt1;
34-1
35-1
36-SHOW STATUS LIKE 'audit_log%';
37-Variable_name Value
38-DEALLOCATE PREPARE stmt1;
39-show variables like 'audit_log%';
40-Variable_name Value
41-audit_log_buffer_size 4096
42-audit_log_file test_audit.log
43-audit_log_flush OFF
44-audit_log_format OLD
45-audit_log_policy ALL
46-audit_log_rotate_on_size 0
47-audit_log_rotations 0
48-audit_log_strategy ASYNCHRONOUS
49-connect(localhost,no_such_user,,mysql,MASTER_PORT,MASTER_SOCKET);
50-ERROR 28000: Access denied for user 'no_such_user'@'localhost' (using password: NO)
51-create table t1 (id int);
52-create table t2 (id int);
53-insert into t1 values (1), (2);
54-insert 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);
55-select * from t1;
56-id
57-1
58-2
59-alter table t1 rename renamed_t1;
60-select * from t_doesnt_exist;
61-ERROR 42S02: Table 'test.t_doesnt_exist' doesn't exist
62-syntax_error_query;
63-ERROR 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
64-drop table renamed_t1, t2;
65-show variables like 'audit_log%';
66-Variable_name Value
67-audit_log_buffer_size 4096
68-audit_log_file test_audit.log
69-audit_log_flush OFF
70-audit_log_format OLD
71-audit_log_policy ALL
72-audit_log_rotate_on_size 0
73-audit_log_rotations 0
74-audit_log_strategy ASYNCHRONOUS
75-create database sa_db;
76-create table t1 (id2 int);
77-insert into t1 values (1), (2);
78-select * from t1;
79-id2
80-1
81-2
82-drop table t1;
83-use sa_db;
84-create table sa_t1(id int);
85-insert into sa_t1 values (1), (2);
86-drop table sa_t1;
87-drop database sa_db;
88-create user 'jeffrey'@'localhost' IDENTIFIED BY 'mypass';
89-drop user 'jeffrey'@'localhost';
90-select '&;&&&""""<><<>>>>';
91-&;&&&""""<><<>>>>
92-&;&&&""""<><<>>>>
93-CREATE TABLE t1 (c1 INT, c2 CHAR(20));
94-CREATE TABLE t1 (c1 INT, c2 CHAR(20));
95-ERROR 42S01: Table 't1' already exists
96-INSERT INTO t1 VALUES (1,'a'),(2,'b'),(3,'c');
97-SELECT * FROM t1;
98-c1 c2
99-1 a
100-2 b
101-3 c
102-SELECT * FROM t2;
103-ERROR 42S02: Table 'test.t2' doesn't exist
104-DROP TABLE t1;
105-PREPARE stmt1 FROM 'SELECT 1';
106-EXECUTE stmt1;
107-1
108-1
109-SHOW STATUS LIKE 'audit_log%';
110-Variable_name Value
111-DEALLOCATE PREPARE stmt1;
112-show variables like 'audit_log%';
113-Variable_name Value
114-audit_log_buffer_size 4096
115-audit_log_file test_audit.log
116-audit_log_flush OFF
117-audit_log_format NEW
118-audit_log_policy LOGINS
119-audit_log_rotate_on_size 0
120-audit_log_rotations 0
121-audit_log_strategy SYNCHRONOUS
122-connect(localhost,no_such_user,,mysql,MASTER_PORT,MASTER_SOCKET);
123-ERROR 28000: Access denied for user 'no_such_user'@'localhost' (using password: NO)
124-create table t1 (id int);
125-create table t2 (id int);
126-insert into t1 values (1), (2);
127-insert 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);
128-select * from t1;
129-id
130-1
131-2
132-alter table t1 rename renamed_t1;
133-select * from t_doesnt_exist;
134-ERROR 42S02: Table 'test.t_doesnt_exist' doesn't exist
135-syntax_error_query;
136-ERROR 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
137-drop table renamed_t1, t2;
138-show variables like 'audit_log%';
139-Variable_name Value
140-audit_log_buffer_size 4096
141-audit_log_file test_audit.log
142-audit_log_flush OFF
143-audit_log_format NEW
144-audit_log_policy LOGINS
145-audit_log_rotate_on_size 0
146-audit_log_rotations 0
147-audit_log_strategy SYNCHRONOUS
148-create database sa_db;
149-create table t1 (id2 int);
150-insert into t1 values (1), (2);
151-select * from t1;
152-id2
153-1
154-2
155-drop table t1;
156-use sa_db;
157-create table sa_t1(id int);
158-insert into sa_t1 values (1), (2);
159-drop table sa_t1;
160-drop database sa_db;
161-create user 'jeffrey'@'localhost' IDENTIFIED BY 'mypass';
162-drop user 'jeffrey'@'localhost';
163-select '&;&&&""""<><<>>>>';
164-&;&&&""""<><<>>>>
165-&;&&&""""<><<>>>>
166+CREATE TABLE t1
167+(c1 INT,
168+c2 CHAR(20));
169+ERROR 42S01: Table 't1' already exists
170+INSERT INTO t1 VALUES (1,'a'),(2,'b'),(3,'c');
171+SELECT * FROM t1;
172+c1 c2
173+1 a
174+2 b
175+3 c
176+SELECT * FROM t2;
177+ERROR 42S02: Table 'test.t2' doesn't exist
178+DROP TABLE t1;
179+PREPARE stmt1 FROM 'SELECT 1';
180+EXECUTE stmt1;
181+1
182+1
183+SHOW STATUS LIKE 'audit_log%';
184+Variable_name Value
185+DEALLOCATE PREPARE stmt1;
186+show variables like 'audit_log%';
187+Variable_name Value
188+audit_log_buffer_size 4096
189+audit_log_file test_audit.log
190+audit_log_flush OFF
191+audit_log_format OLD
192+audit_log_policy ALL
193+audit_log_rotate_on_size 0
194+audit_log_rotations 0
195+audit_log_strategy ASYNCHRONOUS
196+connect(localhost,no_such_user,,mysql,MASTER_PORT,MASTER_SOCKET);
197+ERROR 28000: Access denied for user 'no_such_user'@'localhost' (using password: NO)
198+create table t1 (id int);
199+create table t2 (id int);
200+insert into t1 values (1), (2);
201+insert 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);
202+select * from t1;
203+id
204+1
205+2
206+alter table t1 rename renamed_t1;
207+select * from t_doesnt_exist;
208+ERROR 42S02: Table 'test.t_doesnt_exist' doesn't exist
209+syntax_error_query;
210+ERROR 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
211+drop table renamed_t1, t2;
212+show variables like 'audit_log%';
213+Variable_name Value
214+audit_log_buffer_size 4096
215+audit_log_file test_audit.log
216+audit_log_flush OFF
217+audit_log_format OLD
218+audit_log_policy ALL
219+audit_log_rotate_on_size 0
220+audit_log_rotations 0
221+audit_log_strategy ASYNCHRONOUS
222+create database sa_db;
223+create table t1 (id2 int);
224+insert into t1 values (1), (2);
225+select * from t1;
226+id2
227+1
228+2
229+drop table t1;
230+use sa_db;
231+create table sa_t1(id int);
232+insert into sa_t1 values (1), (2);
233+drop table sa_t1;
234+drop database sa_db;
235+create user 'jeffrey'@'localhost' IDENTIFIED BY 'mypass';
236+drop user 'jeffrey'@'localhost';
237+select '&;&&&""""<><<>>>>';
238+&;&&&""""<><<>>>>
239+&;&&&""""<><<>>>>
240+set global audit_log_flush= ON;
241+CREATE TABLE t1 (c1 INT, c2 CHAR(20));
242+CREATE TABLE t1
243+(c1 INT,
244+c2 CHAR(20));
245+ERROR 42S01: Table 't1' already exists
246+INSERT INTO t1 VALUES (1,'a'),(2,'b'),(3,'c');
247+SELECT * FROM t1;
248+c1 c2
249+1 a
250+2 b
251+3 c
252+SELECT * FROM t2;
253+ERROR 42S02: Table 'test.t2' doesn't exist
254+DROP TABLE t1;
255+PREPARE stmt1 FROM 'SELECT 1';
256+EXECUTE stmt1;
257+1
258+1
259+SHOW STATUS LIKE 'audit_log%';
260+Variable_name Value
261+DEALLOCATE PREPARE stmt1;
262+show variables like 'audit_log%';
263+Variable_name Value
264+audit_log_buffer_size 4096
265+audit_log_file test_audit.log
266+audit_log_flush OFF
267+audit_log_format NEW
268+audit_log_policy LOGINS
269+audit_log_rotate_on_size 0
270+audit_log_rotations 0
271+audit_log_strategy SEMISYNCHRONOUS
272+connect(localhost,no_such_user,,mysql,MASTER_PORT,MASTER_SOCKET);
273+ERROR 28000: Access denied for user 'no_such_user'@'localhost' (using password: NO)
274+create table t1 (id int);
275+create table t2 (id int);
276+insert into t1 values (1), (2);
277+insert 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);
278+select * from t1;
279+id
280+1
281+2
282+alter table t1 rename renamed_t1;
283+select * from t_doesnt_exist;
284+ERROR 42S02: Table 'test.t_doesnt_exist' doesn't exist
285+syntax_error_query;
286+ERROR 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
287+drop table renamed_t1, t2;
288+show variables like 'audit_log%';
289+Variable_name Value
290+audit_log_buffer_size 4096
291+audit_log_file test_audit.log
292+audit_log_flush OFF
293+audit_log_format NEW
294+audit_log_policy LOGINS
295+audit_log_rotate_on_size 0
296+audit_log_rotations 0
297+audit_log_strategy SEMISYNCHRONOUS
298+create database sa_db;
299+create table t1 (id2 int);
300+insert into t1 values (1), (2);
301+select * from t1;
302+id2
303+1
304+2
305+drop table t1;
306+use sa_db;
307+create table sa_t1(id int);
308+insert into sa_t1 values (1), (2);
309+drop table sa_t1;
310+drop database sa_db;
311+create user 'jeffrey'@'localhost' IDENTIFIED BY 'mypass';
312+drop user 'jeffrey'@'localhost';
313+select '&;&&&""""<><<>>>>';
314+&;&&&""""<><<>>>>
315+&;&&&""""<><<>>>>
316+set global audit_log_flush= ON;
317+CREATE TABLE t1 (c1 INT, c2 CHAR(20));
318+CREATE TABLE t1
319+(c1 INT,
320+c2 CHAR(20));
321+ERROR 42S01: Table 't1' already exists
322+INSERT INTO t1 VALUES (1,'a'),(2,'b'),(3,'c');
323+SELECT * FROM t1;
324+c1 c2
325+1 a
326+2 b
327+3 c
328+SELECT * FROM t2;
329+ERROR 42S02: Table 'test.t2' doesn't exist
330+DROP TABLE t1;
331+PREPARE stmt1 FROM 'SELECT 1';
332+EXECUTE stmt1;
333+1
334+1
335+SHOW STATUS LIKE 'audit_log%';
336+Variable_name Value
337+DEALLOCATE PREPARE stmt1;
338+show variables like 'audit_log%';
339+Variable_name Value
340+audit_log_buffer_size 4096
341+audit_log_file test_audit.log
342+audit_log_flush OFF
343+audit_log_format JSON
344+audit_log_policy ALL
345+audit_log_rotate_on_size 0
346+audit_log_rotations 0
347+audit_log_strategy SEMISYNCHRONOUS
348+connect(localhost,no_such_user,,mysql,MASTER_PORT,MASTER_SOCKET);
349+ERROR 28000: Access denied for user 'no_such_user'@'localhost' (using password: NO)
350+create table t1 (id int);
351+create table t2 (id int);
352+insert into t1 values (1), (2);
353+insert 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);
354+select * from t1;
355+id
356+1
357+2
358+alter table t1 rename renamed_t1;
359+select * from t_doesnt_exist;
360+ERROR 42S02: Table 'test.t_doesnt_exist' doesn't exist
361+syntax_error_query;
362+ERROR 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
363+drop table renamed_t1, t2;
364+show variables like 'audit_log%';
365+Variable_name Value
366+audit_log_buffer_size 4096
367+audit_log_file test_audit.log
368+audit_log_flush OFF
369+audit_log_format JSON
370+audit_log_policy ALL
371+audit_log_rotate_on_size 0
372+audit_log_rotations 0
373+audit_log_strategy SEMISYNCHRONOUS
374+create database sa_db;
375+create table t1 (id2 int);
376+insert into t1 values (1), (2);
377+select * from t1;
378+id2
379+1
380+2
381+drop table t1;
382+use sa_db;
383+create table sa_t1(id int);
384+insert into sa_t1 values (1), (2);
385+drop table sa_t1;
386+drop database sa_db;
387+create user 'jeffrey'@'localhost' IDENTIFIED BY 'mypass';
388+drop user 'jeffrey'@'localhost';
389+select '&;&&&""""<><<>>>>';
390+&;&&&""""<><<>>>>
391+&;&&&""""<><<>>>>
392+set global audit_log_flush= ON;
393+CREATE TABLE t1 (c1 INT, c2 CHAR(20));
394+CREATE TABLE t1
395+(c1 INT,
396+c2 CHAR(20));
397+ERROR 42S01: Table 't1' already exists
398+INSERT INTO t1 VALUES (1,'a'),(2,'b'),(3,'c');
399+SELECT * FROM t1;
400+c1 c2
401+1 a
402+2 b
403+3 c
404+SELECT * FROM t2;
405+ERROR 42S02: Table 'test.t2' doesn't exist
406+DROP TABLE t1;
407+PREPARE stmt1 FROM 'SELECT 1';
408+EXECUTE stmt1;
409+1
410+1
411+SHOW STATUS LIKE 'audit_log%';
412+Variable_name Value
413+DEALLOCATE PREPARE stmt1;
414+show variables like 'audit_log%';
415+Variable_name Value
416+audit_log_buffer_size 4096
417+audit_log_file test_audit.log
418+audit_log_flush OFF
419+audit_log_format CSV
420+audit_log_policy ALL
421+audit_log_rotate_on_size 0
422+audit_log_rotations 0
423+audit_log_strategy SEMISYNCHRONOUS
424+connect(localhost,no_such_user,,mysql,MASTER_PORT,MASTER_SOCKET);
425+ERROR 28000: Access denied for user 'no_such_user'@'localhost' (using password: NO)
426+create table t1 (id int);
427+create table t2 (id int);
428+insert into t1 values (1), (2);
429+insert 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);
430+select * from t1;
431+id
432+1
433+2
434+alter table t1 rename renamed_t1;
435+select * from t_doesnt_exist;
436+ERROR 42S02: Table 'test.t_doesnt_exist' doesn't exist
437+syntax_error_query;
438+ERROR 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
439+drop table renamed_t1, t2;
440+show variables like 'audit_log%';
441+Variable_name Value
442+audit_log_buffer_size 4096
443+audit_log_file test_audit.log
444+audit_log_flush OFF
445+audit_log_format CSV
446+audit_log_policy ALL
447+audit_log_rotate_on_size 0
448+audit_log_rotations 0
449+audit_log_strategy SEMISYNCHRONOUS
450+create database sa_db;
451+create table t1 (id2 int);
452+insert into t1 values (1), (2);
453+select * from t1;
454+id2
455+1
456+2
457+drop table t1;
458+use sa_db;
459+create table sa_t1(id int);
460+insert into sa_t1 values (1), (2);
461+drop table sa_t1;
462+drop database sa_db;
463+create user 'jeffrey'@'localhost' IDENTIFIED BY 'mypass';
464+drop user 'jeffrey'@'localhost';
465+select '&;&&&""""<><<>>>>';
466+&;&&&""""<><<>>>>
467+&;&&&""""<><<>>>>
468+set global audit_log_flush= ON;
469
470=== modified file 'mysql-test/t/audit_log.test'
471--- mysql-test/t/audit_log.test 2014-04-21 12:07:45 +0000
472+++ mysql-test/t/audit_log.test 2014-05-26 07:58:11 +0000
473@@ -1,23 +1,77 @@
474 --source include/not_embedded.inc
475
476-# Adjustment to the OS dependent extension of shared libraries.
477-let $expected_extension= so;
478-if(`SELECT CONVERT(@@version_compile_os USING latin1)
479- IN ("Win32","Win64","Windows")`)
480-{
481- let $expected_extension= dll;
482-}
483-
484-let $MYSQL_DATA_DIR= `select @@datadir`;
485-
486---source include/audit_log_events.inc
487-
488---exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
489---shutdown_server
490---source include/wait_until_disconnected.inc
491---enable_reconnect
492---exec echo "restart: --audit_log_policy=LOGINS --audit-log-format=NEW --audit_log_strategy=SYNCHRONOUS" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
493---source include/wait_until_connected_again.inc
494-
495---source include/audit_log_events.inc
496-
497+let $MYSQLD_DATADIR= `select @@datadir`;
498+let MYSQLD_DATADIR= $MYSQLD_DATADIR;
499+
500+--source include/audit_log_events.inc
501+
502+--move_file $MYSQLD_DATADIR/test_audit.log $MYSQLD_DATADIR/test_audit_old.log
503+set global audit_log_flush= ON;
504+perl;
505+ eval "use XML::Parser; 1" or exit 0;
506+ $p = new XML::Parser;
507+ $p->parsefile($ENV{'MYSQLD_DATADIR'} . '/test_audit_old.log');
508+EOF
509+--remove_file $MYSQLD_DATADIR/test_audit.log
510+
511+--exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
512+--shutdown_server
513+--source include/wait_until_disconnected.inc
514+--enable_reconnect
515+--exec echo "restart: --audit_log_policy=LOGINS --audit-log-format=NEW --audit_log_strategy=SEMISYNCHRONOUS" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
516+--source include/wait_until_connected_again.inc
517+
518+--source include/audit_log_events.inc
519+
520+--move_file $MYSQLD_DATADIR/test_audit.log $MYSQLD_DATADIR/test_audit_new.log
521+set global audit_log_flush= ON;
522+perl;
523+ eval "use XML::Parser; 1" or exit 0;
524+ $p = new XML::Parser;
525+ $p->parsefile($ENV{'MYSQLD_DATADIR'} . '/test_audit_new.log');
526+EOF
527+--remove_file $MYSQLD_DATADIR/test_audit.log
528+
529+--exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
530+--shutdown_server
531+--source include/wait_until_disconnected.inc
532+--enable_reconnect
533+--exec echo "restart: --audit-log-format=JSON --audit_log_strategy=SEMISYNCHRONOUS" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
534+--source include/wait_until_connected_again.inc
535+
536+--source include/audit_log_events.inc
537+
538+--move_file $MYSQLD_DATADIR/test_audit.log $MYSQLD_DATADIR/test_audit_json.log
539+set global audit_log_flush= ON;
540+perl;
541+ eval "use JSON qw(decode_json); 1" or exit 0;
542+ open my $file, $ENV{'MYSQLD_DATADIR'} . '/test_audit_json.log' or die "Could not open log: $!";
543+ while (my $line = <$file>) {
544+ decode_json($line);
545+ }
546+ close $file;
547+EOF
548+--remove_file $MYSQLD_DATADIR/test_audit.log
549+
550+--exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
551+--shutdown_server
552+--source include/wait_until_disconnected.inc
553+--enable_reconnect
554+--exec echo "restart: --audit-log-format=CSV --audit_log_strategy=SEMISYNCHRONOUS" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
555+--source include/wait_until_connected_again.inc
556+
557+--source include/audit_log_events.inc
558+
559+--move_file $MYSQLD_DATADIR/test_audit.log $MYSQLD_DATADIR/test_audit_csv.log
560+set global audit_log_flush= ON;
561+perl;
562+ eval "use Text::CSV; 1" or exit 0;
563+ my $p = Text::CSV->new({ binary => 1, auto_diag => 1, sep_char => ',' });
564+ open my $file, $ENV{'MYSQLD_DATADIR'} . '/test_audit_csv.log' or die "Could not open log: $!";
565+ while ($p->getline($file)) {};
566+ if (not $p->eof) {
567+ die "CSV parse error " . $p->error_diag();
568+ }
569+ close $file;
570+EOF
571+--remove_file $MYSQLD_DATADIR/test_audit.log
572
573=== modified file 'plugin/audit_log/audit_log.c'
574--- plugin/audit_log/audit_log.c 2014-05-14 14:32:33 +0000
575+++ plugin/audit_log/audit_log.c 2014-05-26 07:58:11 +0000
576@@ -35,7 +35,9 @@
577 enum audit_log_policy_t { ALL, NONE, LOGINS, QUERIES };
578 enum audit_log_strategy_t
579 { ASYNCHRONOUS, PERFORMANCE, SEMISYNCHRONOUS, SYNCHRONOUS };
580-enum audit_log_format_t { OLD, NEW };
581+enum audit_log_format_t { OLD, NEW, JSON, CSV };
582+
583+typedef void (*escape_buf_func_t)(const char *, size_t *, char *, size_t *);
584
585 static LOGGER_HANDLE *audit_file_logger= NULL;
586 static audit_log_buffer_t *audit_log_buffer= NULL;
587@@ -113,41 +115,37 @@
588 return buf;
589 }
590
591+typedef struct
592+{
593+ char character;
594+ size_t length;
595+ const char *replacement;
596+} escape_rule_t;
597+
598 static
599-void xml_escape(const char *in, size_t *inlen, char* out, size_t *outlen)
600+void escape_buf(const char *in, size_t *inlen, char *out, size_t *outlen,
601+ const escape_rule_t *escape_rules)
602 {
603 char* outstart = out;
604 const char* base = in;
605 char* outend = out + *outlen;
606 const char* inend;
607- size_t i;
608+ const escape_rule_t *rule;
609 my_bool replaced;
610
611- const struct {
612- char symbol;
613- size_t length;
614- const char *replace;
615- } escape[] = {
616- { '<', 4, "&lt;" },
617- { '>', 4, "&gt;" },
618- { '&', 5, "&amp;" },
619- { '\r', 5, "&#13;" },
620- { '"', 6, "&quot;" },
621- };
622-
623 inend = in + (*inlen);
624
625 while ((in < inend) && (out < outend))
626 {
627 replaced= FALSE;
628- for (i= 0; i < array_elements(escape); i++)
629+ for (rule= escape_rules; rule->character; rule++)
630 {
631- if (*in == escape[i].symbol)
632+ if (*in == rule->character)
633 {
634- if ((outend - out) < (int) escape[i].length)
635+ if ((outend - out) < (int) rule->length)
636 goto end_of_buffer;
637- memcpy(out, escape[i].replace, escape[i].length);
638- out += escape[i].length;
639+ memcpy(out, rule->replacement, rule->length);
640+ out += rule->length;
641 replaced= TRUE;
642 break;
643 }
644@@ -161,20 +159,71 @@
645 *inlen = in - base;
646 }
647
648-
649-static
650-char *xml_escape_string(const char *in, size_t inlen,
651- char *out, size_t outlen)
652-{
653+static
654+void xml_escape(const char *in, size_t *inlen, char *out, size_t *outlen)
655+{
656+ const escape_rule_t rules[]=
657+ {
658+ { '<', 4, "&lt;" },
659+ { '>', 4, "&gt;" },
660+ { '&', 5, "&amp;" },
661+ { '\r', 5, "&#13;" },
662+ { '\n', 5, "&#10;" },
663+ { '"', 6, "&quot;" },
664+ { 0, 0, NULL }
665+ };
666+
667+ escape_buf(in, inlen, out, outlen, rules);
668+}
669+
670+static
671+void json_escape(const char *in, size_t *inlen, char *out, size_t *outlen)
672+{
673+ const escape_rule_t rules[]=
674+ {
675+ { '\\', 2, "\\\\" },
676+ { '"', 2, "\\\"" },
677+ { '\r', 2, "\\r" },
678+ { '\n', 2, "\\n" },
679+ { 0, 0, NULL }
680+ };
681+
682+ escape_buf(in, inlen, out, outlen, rules);
683+}
684+
685+static
686+void csv_escape(const char *in, size_t *inlen, char *out, size_t *outlen)
687+{
688+ const escape_rule_t rules[]=
689+ {
690+ { '"', 2, "\"\"" },
691+ { 0, 0, NULL }
692+ };
693+
694+ escape_buf(in, inlen, out, outlen, rules);
695+}
696+
697+static
698+char *escape_string(const char *in, size_t inlen,
699+ char *out, size_t outlen,
700+ char **endptr)
701+{
702+ const escape_buf_func_t format_escape_func[]=
703+ { xml_escape, xml_escape, json_escape, csv_escape };
704+
705 if (in != NULL)
706 {
707 --outlen;
708- xml_escape(in, &inlen, out, &outlen);
709+ format_escape_func[audit_log_format](in, &inlen, out, &outlen);
710 out[outlen]= 0;
711+ if (endptr)
712+ *endptr= out + outlen + 1;
713 }
714 else
715 {
716- out= 0;
717+ *out= 0;
718+ if (endptr)
719+ *endptr= out + 1;
720 }
721 return out;
722 }
723@@ -273,13 +322,14 @@
724 char arg_buf[512];
725 const char *format_string[] = {
726 "<AUDIT_RECORD\n"
727- " \"NAME\"=\"%s\"\n"
728- " \"RECORD\"=\"%s\"\n"
729- " \"TIMESTAMP\"=\"%s\"\n"
730- " \"MYSQL_VERSION\"=\"%s\"\n"
731- " \"STARTUP_OPTIONS\"=\"%s\"\n"
732- " \"OS_VERSION\"=\""MACHINE_TYPE"-"SYSTEM_TYPE"\",\n"
733+ " NAME=\"%s\"\n"
734+ " RECORD=\"%s\"\n"
735+ " TIMESTAMP=\"%s\"\n"
736+ " MYSQL_VERSION=\"%s\"\n"
737+ " STARTUP_OPTIONS=\"%s\"\n"
738+ " OS_VERSION=\""MACHINE_TYPE"-"SYSTEM_TYPE"\"\n"
739 "/>\n",
740+
741 "<AUDIT_RECORD>\n"
742 " <NAME>%s</NAME>\n"
743 " <RECORD>%s</RECORD>\n"
744@@ -287,7 +337,15 @@
745 " <MYSQL_VERSION>%s</MYSQL_VERSION>\n"
746 " <STARTUP_OPTIONS>%s</STARTUP_OPTIONS>\n"
747 " <OS_VERSION>"MACHINE_TYPE"-"SYSTEM_TYPE"</OS_VERSION>\n"
748- "</AUDIT_RECORD>\n" };
749+ "</AUDIT_RECORD>\n",
750+
751+ "{\"audit_record\":{\"name\":\"%s\",\"record\":\"%s\","
752+ "\"timestamp\":\"%s\",\"mysql_version\":\"%s\","
753+ "\"startup_optionsi\":\"%s\","
754+ "\"os_version\":\""MACHINE_TYPE"-"SYSTEM_TYPE"\"}}\n",
755+
756+ "\"%s\",\"%s\",\"%s\",\"%s\",\"%s\","
757+ "\""MACHINE_TYPE"-"SYSTEM_TYPE"\"\n" };
758
759 return my_snprintf(buf, buflen,
760 format_string[audit_log_format],
761@@ -307,21 +365,23 @@
762 {
763 char id_str[MAX_RECORD_ID_SIZE];
764 char timestamp[MAX_TIMESTAMP_SIZE];
765- char query[512];
766+ char query[512], tmp[128];
767+ char *endptr= tmp, *endtmp= tmp + sizeof(tmp);
768 const char *format_string[] = {
769 "<AUDIT_RECORD\n"
770- " \"NAME\"=\"%s\"\n"
771- " \"RECORD\"=\"%s\"\n"
772- " \"TIMESTAMP\"=\"%s\"\n"
773- " \"COMMAND_CLASS\"=\"%s\"\n"
774- " \"CONNECTION_ID\"=\"%lu\"\n"
775- " \"STATUS\"=\"%d\"\n"
776- " \"SQLTEXT\"=\"%s\"\n"
777- " \"USER\"=\"%s\"\n"
778- " \"HOST\"=\"%s\"\n"
779- " \"OS_USER\"=\"%s\"\n"
780- " \"IP\"=\"%s\"\n"
781+ " NAME=\"%s\"\n"
782+ " RECORD=\"%s\"\n"
783+ " TIMESTAMP=\"%s\"\n"
784+ " COMMAND_CLASS=\"%s\"\n"
785+ " CONNECTION_ID=\"%lu\"\n"
786+ " STATUS=\"%d\"\n"
787+ " SQLTEXT=\"%s\"\n"
788+ " USER=\"%s\"\n"
789+ " HOST=\"%s\"\n"
790+ " OS_USER=\"%s\"\n"
791+ " IP=\"%s\"\n"
792 "/>\n",
793+
794 "<AUDIT_RECORD>\n"
795 " <NAME>%s</NAME>\n"
796 " <RECORD>%s</RECORD>\n"
797@@ -334,7 +394,23 @@
798 " <HOST>%s</HOST>\n"
799 " <OS_USER>%s</OS_USER>\n"
800 " <IP>%s</IP>\n"
801- "</AUDIT_RECORD>\n" };
802+ "</AUDIT_RECORD>\n",
803+
804+ "{\"audit_record\":"
805+ "{\"name\":\"%s\","
806+ "\"record\":\"%s\","
807+ "\"timestamp\":\"%s\","
808+ "\"command_class\":\"%s\","
809+ "\"connection_id\":\"%lu\","
810+ "\"status\":%d,"
811+ "\"sqltext\":\"%s\","
812+ "\"user\":\"%s\","
813+ "\"host\":\"%s\","
814+ "\"os_user\":\"%s\","
815+ "\"ip\":\"%s\"}}\n",
816+
817+ "\"%s\",\"%s\",\"%s\",\"%s\",\"%lu\",%d,\"%s\",\"%s\","
818+ "\"%s\",\"%s\",\"%s\"\n" };
819
820 return my_snprintf(buf, buflen,
821 format_string[audit_log_format],
822@@ -343,13 +419,21 @@
823 make_timestamp(timestamp, sizeof(timestamp), t),
824 event->general_sql_command.str,
825 event->general_thread_id, status,
826- xml_escape_string(event->general_query,
827- event->general_query_length,
828- query, sizeof(query)),
829- event->general_user,
830- event->general_host.str,
831- event->general_external_user.str,
832- event->general_ip.str);
833+ escape_string(event->general_query,
834+ event->general_query_length,
835+ query, sizeof(query), NULL),
836+ escape_string(event->general_user,
837+ event->general_user_length,
838+ endptr, endtmp - endptr, &endptr),
839+ escape_string(event->general_host.str,
840+ event->general_host.length,
841+ endptr, endtmp - endptr, &endptr),
842+ escape_string(event->general_external_user.str,
843+ event->general_external_user.length,
844+ endptr, endtmp - endptr, &endptr),
845+ escape_string(event->general_ip.str,
846+ event->general_ip.length,
847+ endptr, endtmp - endptr, &endptr));
848 }
849
850 static
851@@ -359,21 +443,24 @@
852 {
853 char id_str[MAX_RECORD_ID_SIZE];
854 char timestamp[MAX_TIMESTAMP_SIZE];
855+ char tmp[128];
856+ char *endptr= tmp, *endtmp= tmp + sizeof(tmp);
857 const char *format_string[] = {
858 "<AUDIT_RECORD\n"
859- " \"NAME\"=\"%s\"\n"
860- " \"RECORD\"=\"%s\"\n"
861- " \"TIMESTAMP\"=\"%s\"\n"
862- " \"CONNECTION_ID\"=\"%lu\"\n"
863- " \"STATUS\"=\"%d\"\n"
864- " \"USER\"=\"%s\"\n"
865- " \"PRIV_USER\"=\"%s\"\n"
866- " \"OS_LOGIN\"=\"%s\"\n"
867- " \"PROXY_USER\"=\"%s\"\n"
868- " \"HOST\"=\"%s\"\n"
869- " \"IP\"=\"%s\"\n"
870- " \"DB\"=\"%s\"\n"
871+ " NAME=\"%s\"\n"
872+ " RECORD=\"%s\"\n"
873+ " TIMESTAMP=\"%s\"\n"
874+ " CONNECTION_ID=\"%lu\"\n"
875+ " STATUS=\"%d\"\n"
876+ " USER=\"%s\"\n"
877+ " PRIV_USER=\"%s\"\n"
878+ " OS_LOGIN=\"%s\"\n"
879+ " PROXY_USER=\"%s\"\n"
880+ " HOST=\"%s\"\n"
881+ " IP=\"%s\"\n"
882+ " DB=\"%s\"\n"
883 "/>\n",
884+
885 "<AUDIT_RECORD>\n"
886 " <NAME>%s</NAME>\n"
887 " <RECORD>%s</RECORD>\n"
888@@ -387,34 +474,96 @@
889 " <HOST>%s</HOST>\n"
890 " <IP>%s</IP>\n"
891 " <DB>%s</DB>\n"
892- "</AUDIT_RECORD>\n" };
893+ "</AUDIT_RECORD>\n",
894+
895+ "{\"audit_record\":"
896+ "{\"name\":\"%s\","
897+ "\"record\":\"%s\","
898+ "\"timestamp\":\"%s\","
899+ "\"connection_id\":\"%lu\","
900+ "\"status\":%d,"
901+ "\"user\":\"%s\","
902+ "\"priv_user\":\"%s\","
903+ "\"os_login\":\"%s\","
904+ "\"proxy_user\":\"%s\","
905+ "\"host\":\"%s\","
906+ "\"ip\":\"%s\","
907+ "\"db\":\"%s\"}}\n",
908+
909+ "\"%s\",\"%s\",\"%s\",\"%lu\",%d,\"%s\",\"%s\",\"%s\","
910+ "\"%s\",\"%s\",\"%s\",\"%s\"\n" };
911
912 return my_snprintf(buf, buflen,
913 format_string[audit_log_format],
914- name,
915- make_record_id(id_str, sizeof(id_str)),
916- make_timestamp(timestamp, sizeof(timestamp), t),
917- event->thread_id,
918- event->status,
919- event->user ? event->user : "",
920- event->priv_user ? event->priv_user : "",
921- event->external_user ? event->external_user : "",
922- event->proxy_user ? event->proxy_user : "",
923- event->host ? event->host : "",
924- event->ip ? event->ip : "",
925- event->database ? event->database : "");
926-}
927-
928+ name,
929+ make_record_id(id_str, sizeof(id_str)),
930+ make_timestamp(timestamp, sizeof(timestamp), t),
931+ event->thread_id,
932+ event->status,
933+ escape_string(event->user,
934+ event->user_length,
935+ endptr, endtmp - endptr, &endptr),
936+ escape_string(event->priv_user,
937+ event->priv_user_length,
938+ endptr, endtmp - endptr, &endptr),
939+ escape_string(event->external_user,
940+ event->external_user_length,
941+ endptr, endtmp - endptr, &endptr),
942+ escape_string(event->proxy_user,
943+ event->proxy_user_length,
944+ endptr, endtmp - endptr, &endptr),
945+ escape_string(event->host,
946+ event->host_length,
947+ endptr, endtmp - endptr, &endptr),
948+ escape_string(event->user,
949+ event->user_length,
950+ endptr, endtmp - endptr, &endptr),
951+ escape_string(event->ip,
952+ event->ip_length,
953+ endptr, endtmp - endptr, &endptr),
954+ escape_string(event->database,
955+ event->database_length,
956+ endptr, endtmp - endptr, &endptr));
957+}
958+
959+static
960+size_t audit_log_header(MY_STAT *stat, char *buf, size_t buflen)
961+{
962+ const char *format_string[] = {
963+ "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
964+ "<AUDIT>\n",
965+ "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
966+ "<AUDIT>\n",
967+ "",
968+ "" };
969+
970+ log_file_time= stat->st_mtime;
971+
972+ init_record_id(stat->st_size);
973+
974+ return my_snprintf(buf, buflen, format_string[audit_log_format]);
975+}
976+
977+
978+static
979+size_t audit_log_footer(char *buf, size_t buflen)
980+{
981+ const char *format_string[] = {
982+ "</AUDIT>\n",
983+ "</AUDIT>\n",
984+ "",
985+ "" };
986+
987+ return my_snprintf(buf, buflen, format_string[audit_log_format]);
988+}
989
990 static
991 int init_new_log_file()
992 {
993- MY_STAT stat_arg;
994-
995 audit_file_logger= logger_open(audit_log_file, audit_log_rotate_on_size,
996 audit_log_rotate_on_size ? audit_log_rotations : 0,
997 audit_log_strategy >= SEMISYNCHRONOUS,
998- &stat_arg);
999+ audit_log_header);
1000 if (audit_file_logger == NULL)
1001 {
1002 fprintf_timestamp(stderr);
1003@@ -423,10 +572,6 @@
1004 return(1);
1005 }
1006
1007- log_file_time= stat_arg.st_mtime;
1008-
1009- init_record_id(stat_arg.st_size);
1010-
1011 return(0);
1012 }
1013
1014@@ -434,9 +579,7 @@
1015 static
1016 int reopen_log_file()
1017 {
1018- MY_STAT stat_arg;
1019-
1020- if (logger_reopen(audit_file_logger, &stat_arg))
1021+ if (logger_reopen(audit_file_logger, audit_log_header, audit_log_footer))
1022 {
1023 fprintf_timestamp(stderr);
1024 fprintf(stderr, "Cannot open file %s. ", audit_log_file);
1025@@ -444,10 +587,6 @@
1026 return(1);
1027 }
1028
1029- log_file_time= stat_arg.st_mtime;
1030-
1031- init_record_id(stat_arg.st_size);
1032-
1033 return(0);
1034 }
1035
1036@@ -456,7 +595,7 @@
1037 void close_log_file()
1038 {
1039 if (audit_file_logger != NULL)
1040- logger_close(audit_file_logger);
1041+ logger_close(audit_file_logger, audit_log_footer);
1042 }
1043
1044
1045@@ -466,6 +605,8 @@
1046 char buf[1024];
1047 size_t len;
1048
1049+ logger_init_mutexes();
1050+
1051 if (init_new_log_file())
1052 return(1);
1053
1054@@ -494,7 +635,6 @@
1055
1056 if (audit_log_buffer != NULL)
1057 audit_log_buffer_shutdown(audit_log_buffer);
1058-
1059 close_log_file();
1060
1061 return(0);
1062@@ -612,7 +752,7 @@
1063 ASYNCHRONOUS, &audit_log_strategy_typelib);
1064
1065 static const char *audit_log_format_names[]=
1066- { "OLD", "NEW", 0 };
1067+ { "OLD", "NEW", "JSON", "CSV", 0 };
1068 static TYPELIB audit_log_format_typelib=
1069 {
1070 array_elements(audit_log_format_names) - 1, "audit_log_format_typelib",
1071@@ -674,7 +814,7 @@
1072 {
1073 char new_val= *(const char *)(save);
1074
1075- if (new_val != audit_log_flush && new_val == TRUE)
1076+ if (new_val != audit_log_flush && new_val)
1077 {
1078 audit_log_flush= TRUE;
1079 reopen_log_file();
1080
1081=== modified file 'plugin/audit_log/file_logger.c'
1082--- plugin/audit_log/file_logger.c 2014-04-21 12:07:45 +0000
1083+++ plugin/audit_log/file_logger.c 2014-05-26 07:58:11 +0000
1084@@ -13,12 +13,11 @@
1085 along with this program; if not, write to the Free Software
1086 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
1087
1088-#include <string.h>
1089-
1090+#include <my_global.h>
1091 #include <mysql/plugin.h>
1092-#include <my_global.h>
1093 #include <my_sys.h>
1094 #include <my_pthread.h>
1095+#include <string.h>
1096
1097 #include "logger.h"
1098
1099@@ -85,14 +84,17 @@
1100 return (i == 0) ? 0 : ((i < 10) ? 1 : ((i < 100) ? 2 : 3));
1101 }
1102
1103-
1104 LOGGER_HANDLE *logger_open(const char *path,
1105 unsigned long long size_limit,
1106 unsigned int rotations,
1107 int thread_safe,
1108- MY_STAT *stat)
1109+ logger_prolog_func_t header)
1110 {
1111 LOGGER_HANDLE new_log, *l_perm;
1112+ MY_STAT stat_arg;
1113+ char buf[128];
1114+ size_t len;
1115+
1116 /*
1117 I don't think we ever need more rotations,
1118 but if it's so, the rotation procedure should be adapted to it.
1119@@ -113,22 +115,19 @@
1120 return 0;
1121 }
1122
1123- if ((new_log.file= open(new_log.path, LOG_FLAGS, 0666)) < 0)
1124+ if ((new_log.file= my_open(new_log.path, LOG_FLAGS, 0666)) < 0)
1125 {
1126 errno= my_errno;
1127 /* Check errno for the cause */
1128 return 0;
1129 }
1130
1131- if (stat != NULL)
1132+ if (my_fstat(new_log.file, &stat_arg, MYF(0)))
1133 {
1134- if (my_fstat(new_log.file, stat, MYF(0)))
1135- {
1136- errno= my_errno;
1137- my_close(new_log.file, MYF(0));
1138- new_log.file= -1;
1139- return 0;
1140- }
1141+ errno= my_errno;
1142+ my_close(new_log.file, MYF(0));
1143+ new_log.file= -1;
1144+ return 0;
1145 }
1146
1147 if (!(l_perm= (LOGGER_HANDLE *) my_malloc(sizeof(LOGGER_HANDLE), MYF(0))))
1148@@ -139,22 +138,25 @@
1149 }
1150 *l_perm= new_log;
1151
1152-#if defined(HAVE_PSI_INTERFACE) && !defined(FLOGGER_NO_PSI) && !defined(FLOGGER_NO_THREADSAFE)
1153- if (PSI_server)
1154- PSI_server->register_mutex("file_logger",
1155- mutex_list, array_elements(mutex_list));
1156-#endif /*HAVE_PSI_INTERFACE && !FLOGGER_NO_PSI*/
1157-
1158 flogger_mutex_init(key_LOCK_logger_service, l_perm,
1159 MY_MUTEX_INIT_FAST);
1160
1161+ len= header(&stat_arg, buf, sizeof(buf));
1162+ my_write(l_perm->file, (uchar *)buf, len, MYF(0));
1163+
1164 return l_perm;
1165 }
1166
1167-int logger_close(LOGGER_HANDLE *log)
1168+int logger_close(LOGGER_HANDLE *log, logger_epilog_func_t footer)
1169 {
1170 int result;
1171 File file= log->file;
1172+ char buf[128];
1173+ size_t len;
1174+
1175+ len= footer(buf, sizeof(buf));
1176+ my_write(file, (uchar *)buf, len, MYF(0));
1177+
1178 flogger_mutex_destroy(log);
1179 my_free(log);
1180 if ((result= my_close(file, MYF(0))))
1181@@ -163,12 +165,19 @@
1182 }
1183
1184
1185-int logger_reopen(LOGGER_HANDLE *log, MY_STAT *stat)
1186+int logger_reopen(LOGGER_HANDLE *log, logger_prolog_func_t header,
1187+ logger_epilog_func_t footer)
1188 {
1189 int result= 0;
1190+ MY_STAT stat_arg;
1191+ char buf[128];
1192+ size_t len;
1193
1194 flogger_mutex_lock(log);
1195
1196+ len= footer(buf, sizeof(buf));
1197+ my_write(log->file, (uchar *)buf, len, MYF(0));
1198+
1199 if ((result= my_close(log->file, MYF(0))))
1200 {
1201 errno= my_errno;
1202@@ -182,19 +191,19 @@
1203 goto error;
1204 }
1205
1206- if (stat != NULL)
1207+ if ((result= my_fstat(log->file, &stat_arg, MYF(0))))
1208 {
1209- if ((result= my_fstat(log->file, stat, MYF(0))))
1210- {
1211- errno= my_errno;
1212- goto error;
1213- }
1214+ errno= my_errno;
1215+ goto error;
1216 }
1217
1218+ len= header(&stat_arg, buf, sizeof(buf));
1219+ my_write(log->file, (uchar *)buf, len, MYF(0));
1220+
1221 error:
1222 flogger_mutex_unlock(log);
1223
1224- return 0;
1225+ return result;
1226 }
1227
1228
1229
1230=== modified file 'plugin/audit_log/logger.h'
1231--- plugin/audit_log/logger.h 2014-04-21 12:07:45 +0000
1232+++ plugin/audit_log/logger.h 2014-05-26 07:58:11 +0000
1233@@ -60,20 +60,23 @@
1234 #endif
1235
1236 typedef struct logger_handle_st LOGGER_HANDLE;
1237+typedef size_t (logger_prolog_func_t)(MY_STAT *, char *buf, size_t buflen);
1238+typedef size_t (logger_epilog_func_t)(char *buf, size_t buflen);
1239
1240 void logger_init_mutexes();
1241 LOGGER_HANDLE *logger_open(const char *path,
1242 unsigned long long size_limit,
1243 unsigned int rotations,
1244 int thread_safe,
1245- MY_STAT *stat);
1246-int logger_close(LOGGER_HANDLE *log);
1247+ logger_prolog_func_t header);
1248+int logger_close(LOGGER_HANDLE *log, logger_epilog_func_t footer);
1249 int logger_vprintf(LOGGER_HANDLE *log, const char *fmt, va_list argptr);
1250 int logger_printf(LOGGER_HANDLE *log, const char *fmt, ...);
1251 int logger_write(LOGGER_HANDLE *log, const char *buffer, size_t size);
1252 int logger_rotate(LOGGER_HANDLE *log);
1253 int logger_sync(LOGGER_HANDLE *log);
1254-int logger_reopen(LOGGER_HANDLE *log, MY_STAT *stat);
1255+int logger_reopen(LOGGER_HANDLE *log, logger_prolog_func_t header,
1256+ logger_epilog_func_t footer);
1257 void logger_set_size_limit(LOGGER_HANDLE *log, unsigned long long size_limit);
1258 void logger_set_rotations(LOGGER_HANDLE *log, unsigned int rotations);
1259

Subscribers

People subscribed via source and target branches