Merge lp:~sergei.glushchenko/percona-server/5.6-ps-bug1320879 into lp:percona-server/5.6
- 5.6-ps-bug1320879
- Merge into 5.6
Proposed by
Sergei Glushchenko
Status: | Merged | ||||
---|---|---|---|---|---|
Approved by: | Laurynas Biveinis | ||||
Approved revision: | no longer in the source branch. | ||||
Merged at revision: | 627 | ||||
Proposed branch: | lp:~sergei.glushchenko/percona-server/5.6-ps-bug1320879 | ||||
Merge into: | lp:percona-server/5.6 | ||||
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.6-ps-bug1320879 | ||||
Related bugs: |
|
||||
Related blueprints: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Laurynas Biveinis (community) | Approve | ||
Review via email: mp+220837@code.launchpad.net |
Commit message
Description of the change
To post a comment you must log in.
Revision history for this message
George Ormond Lorch III (gl-az) wrote : | # |
Revision history for this message
Sergei Glushchenko (sergei.glushchenko) wrote : | # |
Hi George! Thanks for looking into this. It makes sense. I am testing that all log formats can handle newline characters inside query. Important for JSON since it cannot have newline characters inside the string.
Revision history for this message
George Ormond Lorch III (gl-az) wrote : | # |
Ahh, that makes sense now, thanks sergei.
While I don't think it is necessary to change here, in the future I would suggest adding a comment to inform the next guy that the formatting is actually part of the test and not done solely for aesthetic reasons.
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
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-23 17:37:12 +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-23 17:37:12 +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-23 17:37:12 +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-23 17:37:12 +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, "<" }, |
617 | - { '>', 4, ">" }, |
618 | - { '&', 5, "&" }, |
619 | - { '\r', 5, " " }, |
620 | - { '"', 6, """ }, |
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, "<" }, |
659 | + { '>', 4, ">" }, |
660 | + { '&', 5, "&" }, |
661 | + { '\r', 5, " " }, |
662 | + { '\n', 5, " " }, |
663 | + { '"', 6, """ }, |
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-23 17:37:12 +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-23 17:37:12 +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 |
Hey Sergei, events. inc is formatting only? This doesn't seem to be really necessary.
Is there any reason that the CREATE TABLE change in audit_log_