Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GRD-64290 & GRD-78943 : Fixed timezone issue and database type value #589

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@

## 1.1.7
- More formatted exception description is added.
- Support for all timezone.

## 1.0.0
- Stable version

### Added
- Initial release, in parallel to Guardium v11.4.



Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
filter{
# For this to work, the Filebeat configuration on your data source should tag the events it is sending.
if [type] == "filebeat" and "guc_filter_param_datasource_tag" in [tags] {

mutate { add_field => {"minOff" => "%{[event][timezone]}" }}
mutate { add_field => { "source_program" => "percona-audit" } }
mutate { add_field => { "server_hostname" => "%{[host][name]}" } }
mutate { add_field => { "server_ip" => "%{[host][ip][0]}" } }
mutate { replace => { "message" => "percona-audit: %{message}" } }

mysql_percona_filter {}

# keep original event fields, for debugging
Expand All @@ -18,4 +20,4 @@ filter{
}
}
}
}
}
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1.0.7
1.1.7
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ filter {

# For this to work, the Filebeat configuration on your data source should tag the events it is sending.
if [type] == "filebeat" and "mysqlpercona" in [tags] {

mutate { add_field => {"minOff" => "%{[event][timezone]}" }}
mutate { add_field => { "source_program" => "percona-audit" } }
mutate { add_field => { "client_hostname" => "%{[agent][hostname]}" } }
mutate { add_field => { "server_hostname" => "%{[host][hostname]}" } }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
import co.elastic.logstash.api.FilterMatchListener;
import co.elastic.logstash.api.LogstashPlugin;
import co.elastic.logstash.api.PluginConfigSpec;
import java.time.ZoneId;
import java.time.format.DateTimeParseException;

import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.LogManager;
Expand Down Expand Up @@ -41,7 +43,7 @@ public class MySqlPerconaFilter implements Filter {
private static final String MYSQL_AUDIT_START_SIGNAL = "percona-audit: ";
public static final String DATA_PROTOCOL_STRING = "MySQL Percona audit";
public static final String UNKNOWN_STRING = "";
public static final String SERVER_TYPE_STRING = "MySql";
public static final String SERVER_TYPE_STRING = "PERCONA_MYSQL";

private static Logger log = LogManager.getLogger(MySqlPerconaFilter.class);

Expand Down Expand Up @@ -151,7 +153,13 @@ public Collection<Event> filter(Collection<Event> events, FilterMatchListener ma

record.setAppUserName(UNKNOWN_STRING);

Time time = getTime(getFieldAsString(audit_record, "timestamp", null));
String minOff = "+00:00" ;
if(e.getField("minOff") != null)
{
minOff = e.getField("minOff").toString();
}
Time time = getTime(getFieldAsString(audit_record, "timestamp", null),minOff);

record.setTime(time);

record.setSessionLocator(parseSessionLocator(e, audit_record));
Expand Down Expand Up @@ -187,14 +195,29 @@ private static String getFieldAsString(JsonObject jsonObject, String fieldName,
return jsonObject.get(fieldName).getAsString();
}

public static Time getTime(String dateString){
public static Time getTime(String dateString, String timeZone){
if (dateString == null){
log.warn("DateString is null");
return new Time(0, 0, 0);
}
ZonedDateTime date = ZonedDateTime.parse(dateString, DATE_TIME_FORMATTER);
long millis = date.toInstant().toEpochMilli();
int minOffset = date.getOffset().getTotalSeconds()/60;

ZoneOffset offset = ZoneOffset.of(ZoneOffset.UTC.getId());
if (timeZone != null) {
offset = ZoneOffset.of(timeZone);
}

ZonedDateTime date;
try {
date = ZonedDateTime.parse(dateString, DATE_TIME_FORMATTER);
}
catch(DateTimeParseException e){
DateTimeFormatter formatter = DateTimeFormatter.ISO_INSTANT;
date = ZonedDateTime.parse(dateString, formatter.withZone(offset));
}

ZonedDateTime zdt = date.withZoneSameInstant(offset);
long millis = zdt.toInstant().toEpochMilli();
int minOffset = zdt.getOffset().getTotalSeconds() / 60;
//int minDst = date.getOffset().getRules().isDaylightSavings(date.toInstant()) ? 60 : 0;
return new Time(millis, minOffset, 0);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,11 @@
import co.elastic.logstash.api.Context;
import co.elastic.logstash.api.Event;
import co.elastic.logstash.api.FilterMatchListener;
import com.google.gson.Gson;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.ibm.guardium.universalconnector.commons.GuardConstants;
import com.ibm.guardium.universalconnector.commons.structures.Record;
import org.junit.Assert;
import org.junit.Test;
import org.logstash.plugins.ConfigurationImpl;
Expand Down Expand Up @@ -82,26 +86,34 @@ public void testParseMySqlPercona_Data1(){
"\t\t\t\t\t\t\t\t\t\t\t\t\"ip\":\"\",\n" +
"\t\t\t\t\t\t\t\t\t\t\t\t\"db\":\"gdb\"}\n" +
"\t\t\t\t\t\t\t\t\t}";
String minOff = "+07:00";


Configuration config = new ConfigurationImpl(Collections.singletonMap("log_level", "debug"));
Context context = new ContextImpl(null, null);
MySqlPerconaFilter filter = new MySqlPerconaFilter("test-id", config, context);

Event e = new org.logstash.Event();
TestMatchListener matchListener = new TestMatchListener();

e.setField("minOff", minOff);
e.setField("message", mysql_message);
Collection<Event> results = filter.filter(Collections.singletonList(e), matchListener);

Assert.assertEquals(1, results.size());
Assert.assertNotNull(e.getField(GuardConstants.GUARDIUM_RECORD_FIELD_NAME));
Assert.assertEquals(1, matchListener.getMatchCount());
System.out.println(e.getField(GuardConstants.GUARDIUM_RECORD_FIELD_NAME));
Record record = new Gson().fromJson((String)e.getField(GuardConstants.GUARDIUM_RECORD_FIELD_NAME), Record.class);
Assert.assertEquals(record.getDbName(), record.getAccessor().getServiceName());

}

@Test
public void testParseMySqlPercona_Error(){
String error_message = "percona-audit: {\"audit_record\":{\"name\":\"Query\",\"record\":\"39_2021-02-03T18:54:45\",\"timestamp\":\"2021-02-03T18:55:57 UTC\",\"command_class\":\"select\",\"connection_id\":\"2\",\"status\":1146,\"sqltext\":\"select * from users\",\"user\":\"root[root] @ localhost []\",\"host\":\"localhost\",\"os_user\":\"\",\"ip\":\"\",\"db\":\"mysql\"}}";
String minOff = "+04:00";

Configuration config = new ConfigurationImpl(Collections.singletonMap("source", "message"));
Context context = new ContextImpl(null, null);
MySqlPerconaFilter filter = new MySqlPerconaFilter("test-id", config, context);
Expand All @@ -110,6 +122,7 @@ public void testParseMySqlPercona_Error(){
TestMatchListener matchListener = new TestMatchListener();

e.setField("message", error_message);
e.setField("minOff", minOff);
Collection<Event> results = filter.filter(Collections.singletonList(e), matchListener);

Assert.assertEquals(1, results.size());
Expand Down Expand Up @@ -138,6 +151,26 @@ public void testParseMySqlPercona_AccessDenied(){
Assert.assertEquals(1, matchListener.getMatchCount());
System.out.println(e.getField(GuardConstants.GUARDIUM_RECORD_FIELD_NAME));
}

@Test
public void testParseMySqlPercona_Data2(){
String mysql_message = "<14>Feb 12 07:18:30 dbqa09 percona-audit: {\"audit_record\":{\"name\":\"Query\",\"record\":\"106_1970-01-01T00:00:00\",\"timestamp\":\"2021-02-12T12:18:30Z\",\"command_class\":\"select\",\"connection_id\":\"12\",\"status\":0,\"sqltext\":\"select * from Products limit 99999\",\"user\":\"root[root] @ localhost []\",\"host\":\"localhost\",\"os_user\":\"\",\"ip\":\"\",\"db\":\"\"}}";
Configuration config = new ConfigurationImpl(Collections.singletonMap("log_level", "debug"));
Context context = new ContextImpl(null, null);
MySqlPerconaFilter filter = new MySqlPerconaFilter("test-id", config, context);

Event e = new org.logstash.Event();
TestMatchListener matchListener = new TestMatchListener();

e.setField("message", mysql_message);
Collection<Event> results = filter.filter(Collections.singletonList(e), matchListener);

Assert.assertEquals(1, results.size());
Assert.assertNotNull(e.getField(GuardConstants.GUARDIUM_RECORD_FIELD_NAME));
Assert.assertEquals(1, matchListener.getMatchCount());
System.out.println(e.getField(GuardConstants.GUARDIUM_RECORD_FIELD_NAME));
}

}

class TestMatchListener implements FilterMatchListener {
Expand Down
Loading