/** * This file is part of Graylog. * * Graylog is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Graylog is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Graylog. If not, see <http://www.gnu.org/licenses/>. */ package org.graylog2.inputs.extractors; import com.google.common.collect.Lists; import com.google.common.collect.Sets; import org.graylog2.ConfigurationException; import org.graylog2.grok.GrokPattern; import org.graylog2.plugin.LocalMetricRegistry; import org.graylog2.plugin.inputs.Converter; import org.graylog2.plugin.inputs.Extractor; import org.joda.time.DateTime; import org.joda.time.DateTimeZone; import org.junit.Before; import org.junit.Test; import java.util.Date; import java.util.HashMap; import java.util.Map; import java.util.Set; import static org.assertj.core.api.Assertions.assertThat; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; public class GrokExtractorTest { private Set<GrokPattern> patternSet; @Before public void setUp() throws Exception { patternSet = Sets.newHashSet(); final GrokPattern baseNum = GrokPattern.create("BASE10NUM", "(?<![0-9.+-])(?>[+-]?(?:(?:[0-9]+(?:\\.[0-9]+)?)|(?:\\.[0-9]+)))"); final GrokPattern number = GrokPattern.create("NUMBER", "(?:%{BASE10NUM:UNWANTED})"); final GrokPattern data = GrokPattern.create("GREEDY", ".*"); patternSet.add(baseNum); patternSet.add(number); patternSet.add(data); } @Test public void testDatatypeExtraction() { final GrokExtractor extractor = makeExtractor("%{NUMBER:number;int}"); final Extractor.Result[] results = extractor.run("199999"); assertEquals("NUMBER is marked as UNWANTED and does not generate a field", 1, results.length); assertEquals(Integer.class, results[0].getValue().getClass()); assertEquals(199999, results[0].getValue()); } @Test public void testDateExtraction() { final GrokExtractor extractor = makeExtractor("%{GREEDY:timestamp;date;yyyy-MM-dd'T'HH:mm:ss.SSSX}"); final Extractor.Result[] results = extractor.run("2015-07-31T10:05:36.773Z"); assertEquals("ISO date is parsed", 1, results.length); Object value = results[0].getValue(); assertTrue(value instanceof Date); DateTime date = new DateTime(value, DateTimeZone.UTC); assertEquals(2015, date.getYear()); assertEquals(7, date.getMonthOfYear()); assertEquals(31, date.getDayOfMonth()); assertEquals(10, date.getHourOfDay()); assertEquals(5, date.getMinuteOfHour()); assertEquals(36, date.getSecondOfMinute()); assertEquals(773, date.getMillisOfSecond()); } @Test public void testNamedCapturesOnly() throws Exception { final Map<String, Object> config = new HashMap<>(); final GrokPattern mynumber = GrokPattern.create("MYNUMBER", "(?:%{BASE10NUM})"); patternSet.add(mynumber); config.put("named_captures_only", true); final GrokExtractor extractor1 = makeExtractor("%{MYNUMBER:num}", config); config.put("named_captures_only", true); final GrokExtractor extractor2 = makeExtractor("%{MYNUMBER:num;int}", config); config.put("named_captures_only", false); final GrokExtractor extractor3 = makeExtractor("%{MYNUMBER:num}", config); final GrokExtractor extractor4 = makeExtractor("%{MYNUMBER:num}"); assertThat(extractor1.run("2015")) .hasSize(1) .containsOnly(new Extractor.Result("2015", "num", -1, -1)); assertThat(extractor2.run("2015")) .hasSize(1) .containsOnly(new Extractor.Result(2015, "num", -1, -1)); assertThat(extractor3.run("2015")) .hasSize(2) .containsOnly( new Extractor.Result("2015", "num", -1, -1), new Extractor.Result("2015", "BASE10NUM", -1, -1) ); assertThat(extractor4.run("2015")) .hasSize(2) .containsOnly( new Extractor.Result("2015", "num", -1, -1), new Extractor.Result("2015", "BASE10NUM", -1, -1) ); } private GrokExtractor makeExtractor(String pattern) { return makeExtractor(pattern, new HashMap<>()); } private GrokExtractor makeExtractor(String pattern, Map<String, Object> config) { config.put("grok_pattern", pattern); try { return new GrokExtractor(new LocalMetricRegistry(), patternSet, "id", "title", 0, Extractor.CursorStrategy.COPY, "message", "message", config, "admin", Lists.<Converter>newArrayList(), Extractor.ConditionType.NONE, null); } catch (Extractor.ReservedFieldException | ConfigurationException e) { fail("Test setup is wrong: " + e.getMessage()); throw new RuntimeException(e); } } }