nl.basjes.parse.dissectors.http.TimeStampDissector.java Source code

Java tutorial

Introduction

Here is the source code for nl.basjes.parse.dissectors.http.TimeStampDissector.java

Source

/*
 * Apache HTTPD logparsing made easy
 * Copyright (C) 2011-2015 Niels Basjes
 *
 * This program 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.
    
 * This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package nl.basjes.parse.dissectors.http;

import nl.basjes.parse.core.Casts;
import nl.basjes.parse.core.Dissector;
import nl.basjes.parse.core.Parsable;
import nl.basjes.parse.core.ParsedField;
import nl.basjes.parse.core.exceptions.DissectionFailure;
import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.*;

public class TimeStampDissector extends Dissector {

    private static final Logger LOG = LoggerFactory.getLogger(TimeStampDissector.class);

    // --------------------------------------------

    private DateTimeFormatter formatter;
    private DateTimeFormatter asParsedFormatter;
    private String dateTimePattern;

    @SuppressWarnings("UnusedDeclaration")
    public TimeStampDissector() {
        // We set the default parser to what we find in the Apache httpd Logfiles
        //                  [05/Sep/2010:11:27:50 +0200]
        setDateTimePattern("[dd/MMM/yyyy:HH:mm:ss ZZ]");
    }

    public TimeStampDissector(String newDateTimePattern) {
        setDateTimePattern(newDateTimePattern);
    }

    // --------------------------------------------

    @Override
    public boolean initializeFromSettingsParameter(String settings) {
        // There is only one setting for this dissector
        setDateTimePattern(settings);
        return true; // Everything went right.
    }

    // --------------------------------------------

    public void setDateTimePattern(String newDateTimePattern) {
        dateTimePattern = newDateTimePattern;
        formatter = DateTimeFormat.forPattern(dateTimePattern).withZone(DateTimeZone.UTC);
        asParsedFormatter = formatter.withOffsetParsed();
    }

    @Override
    protected void initializeNewInstance(Dissector newInstance) {
        ((TimeStampDissector) newInstance).setDateTimePattern(dateTimePattern);
    }

    // --------------------------------------------

    private static final String INPUT_TYPE = "TIME.STAMP";

    @Override
    public String getInputType() {
        return INPUT_TYPE;
    }

    // --------------------------------------------

    @Override
    public List<String> getPossibleOutput() {
        List<String> result = new ArrayList<>();
        // As parsed
        result.add("TIME.DAY:day");
        result.add("TIME.MONTHNAME:monthname");
        result.add("TIME.MONTH:month");
        result.add("TIME.WEEK:weekofweekyear");
        result.add("TIME.YEAR:weekyear");
        result.add("TIME.YEAR:year");
        result.add("TIME.HOUR:hour");
        result.add("TIME.MINUTE:minute");
        result.add("TIME.SECOND:second");
        result.add("TIME.MILLISECOND:millisecond");

        // Timezone independent
        result.add("TIME.ZONE:timezone");
        result.add("TIME.EPOCH:epoch");

        // In UTC timezone
        result.add("TIME.DAY:day_utc");
        result.add("TIME.MONTHNAME:monthname_utc");
        result.add("TIME.MONTH:month_utc");
        result.add("TIME.WEEK:weekofweekyear_utc");
        result.add("TIME.YEAR:weekyear_utc");
        result.add("TIME.YEAR:year_utc");
        result.add("TIME.HOUR:hour_utc");
        result.add("TIME.MINUTE:minute_utc");
        result.add("TIME.SECOND:second_utc");
        result.add("TIME.MILLISECOND:millisecond_utc");

        return result;
    }

    // --------------------------------------------

    private boolean wantAnyAsParsed = false;
    private boolean wantAnyUTC = false;
    private boolean wantAnyTZIndependent = false;

    // As parsed
    private boolean wantDay = false;
    private boolean wantMonthname = false;
    private boolean wantMonth = false;
    private boolean wantWeekOfWeekYear = false;
    private boolean wantWeekYear = false;
    private boolean wantYear = false;
    private boolean wantHour = false;
    private boolean wantMinute = false;
    private boolean wantSecond = false;
    private boolean wantMillisecond = false;

    // Timezone independent
    private boolean wantTimezone = false;
    private boolean wantEpoch = false;

    // In UTC timezone
    private boolean wantDayUTC = false;
    private boolean wantMonthnameUTC = false;
    private boolean wantMonthUTC = false;
    private boolean wantWeekOfWeekYearUTC = false;
    private boolean wantWeekYearUTC = false;
    private boolean wantYearUTC = false;
    private boolean wantHourUTC = false;
    private boolean wantMinuteUTC = false;
    private boolean wantSecondUTC = false;
    private boolean wantMillisecondUTC = false;

    @Override
    public EnumSet<Casts> prepareForDissect(final String inputname, final String outputname) {
        String name = outputname.substring(inputname.length() + 1);
        switch (name) {
        // As parsed
        case "day":
            wantDay = true;
            return Casts.STRING_OR_LONG;

        case "monthname":
            wantMonthname = true;
            return Casts.STRING_ONLY;

        case "month":
            wantMonth = true;
            return Casts.STRING_OR_LONG;

        case "weekofweekyear":
            wantWeekOfWeekYear = true;
            return Casts.STRING_OR_LONG;

        case "weekyear":
            wantWeekYear = true;
            return Casts.STRING_OR_LONG;

        case "year":
            wantYear = true;
            return Casts.STRING_OR_LONG;

        case "hour":
            wantHour = true;
            return Casts.STRING_OR_LONG;

        case "minute":
            wantMinute = true;
            return Casts.STRING_OR_LONG;

        case "second":
            wantSecond = true;
            return Casts.STRING_OR_LONG;

        case "millisecond":
            wantMillisecond = true;
            return Casts.STRING_OR_LONG;

        // Timezone independent
        case "timezone":
            wantTimezone = true;
            return Casts.STRING_ONLY;

        case "epoch":
            wantEpoch = true;
            return Casts.STRING_OR_LONG;

        // In UTC timezone
        case "day_utc":
            wantDayUTC = true;
            return Casts.STRING_OR_LONG;

        case "monthname_utc":
            wantMonthnameUTC = true;
            return Casts.STRING_ONLY;

        case "month_utc":
            wantMonthUTC = true;
            return Casts.STRING_OR_LONG;

        case "weekofweekyear_utc":
            wantWeekOfWeekYearUTC = true;
            return Casts.STRING_OR_LONG;

        case "weekyear_utc":
            wantWeekYearUTC = true;
            return Casts.STRING_OR_LONG;

        case "year_utc":
            wantYearUTC = true;
            return Casts.STRING_OR_LONG;

        case "hour_utc":
            wantHourUTC = true;
            return Casts.STRING_OR_LONG;

        case "minute_utc":
            wantMinuteUTC = true;
            return Casts.STRING_OR_LONG;

        case "second_utc":
            wantSecondUTC = true;
            return Casts.STRING_OR_LONG;

        case "millisecond_utc":
            wantMillisecondUTC = true;
            return Casts.STRING_OR_LONG;

        default:
            return null;
        }
    }

    // --------------------------------------------

    @Override
    public void prepareForRun() {
        // As parsed
        wantAnyAsParsed = wantDay || wantMonthname || wantMonth || wantWeekOfWeekYear || wantWeekYear || wantYear
                || wantHour || wantMinute || wantSecond || wantMillisecond;

        // Timezone independent
        wantAnyTZIndependent = wantTimezone || wantEpoch;

        // In UTC timezone
        wantAnyUTC = wantDayUTC || wantMonthnameUTC || wantMonthUTC || wantWeekOfWeekYearUTC || wantWeekYearUTC
                || wantYearUTC || wantHourUTC || wantMinuteUTC || wantSecondUTC || wantMillisecondUTC;
    }

    // --------------------------------------------

    @Override
    public void dissect(final Parsable<?> parsable, final String inputname) throws DissectionFailure {
        final ParsedField field = parsable.getParsableField(INPUT_TYPE, inputname);
        final String fieldValue = field.getValue();
        if (fieldValue == null || fieldValue.isEmpty()) {
            return; // Nothing to do here
        }

        if (wantAnyAsParsed || wantAnyTZIndependent) {
            // FIXME: YUCK ! Parsing the same thing TWICE just for the Zone ?!?!?
            DateTime dateTime = asParsedFormatter.parseDateTime(fieldValue);
            DateTimeZone zone = dateTime.getZone();
            DateTimeFormatter asParsedWithZoneFormatter = asParsedFormatter.withZone(zone);
            dateTime = asParsedWithZoneFormatter.parseDateTime(fieldValue);

            // As parsed
            if (wantDay) {
                parsable.addDissection(inputname, "TIME.DAY", "day", dateTime.dayOfMonth().getAsString());
            }
            if (wantMonthname) {
                parsable.addDissection(inputname, "TIME.MONTHNAME", "monthname",
                        dateTime.monthOfYear().getAsText(Locale.getDefault()));
            }
            if (wantMonth) {
                parsable.addDissection(inputname, "TIME.MONTH", "month", dateTime.monthOfYear().getAsString());
            }
            if (wantWeekOfWeekYear) {
                parsable.addDissection(inputname, "TIME.WEEK", "weekofweekyear",
                        dateTime.weekOfWeekyear().getAsString());
            }
            if (wantWeekYear) {
                parsable.addDissection(inputname, "TIME.YEAR", "weekyear", dateTime.weekyear().getAsString());
            }
            if (wantYear) {
                parsable.addDissection(inputname, "TIME.YEAR", "year", dateTime.year().getAsString());
            }
            if (wantHour) {
                parsable.addDissection(inputname, "TIME.HOUR", "hour", dateTime.hourOfDay().getAsString());
            }
            if (wantMinute) {
                parsable.addDissection(inputname, "TIME.MINUTE", "minute", dateTime.minuteOfHour().getAsString());
            }
            if (wantSecond) {
                parsable.addDissection(inputname, "TIME.SECOND", "second", dateTime.secondOfMinute().getAsString());
            }
            if (wantMillisecond) {
                parsable.addDissection(inputname, "TIME.MILLISECOND", "millisecond",
                        dateTime.millisOfSecond().getAsString());
            }

            // Timezone independent
            if (wantTimezone) {
                parsable.addDissection(inputname, "TIME.TIMEZONE", "timezone", dateTime.getZone().getID());
            }
            if (wantEpoch) {
                parsable.addDissection(inputname, "TIME.EPOCH", "epoch", Long.toString(dateTime.getMillis()));
            }
        }

        if (wantAnyUTC) {
            // In UTC timezone
            DateTime dateTime = formatter.parseDateTime(fieldValue);

            if (wantDayUTC) {
                parsable.addDissection(inputname, "TIME.DAY", "day_utc", dateTime.dayOfMonth().getAsString());
            }
            if (wantMonthnameUTC) {
                parsable.addDissection(inputname, "TIME.MONTHNAME", "monthname_utc",
                        dateTime.monthOfYear().getAsText(Locale.getDefault()));
            }
            if (wantMonthUTC) {
                parsable.addDissection(inputname, "TIME.MONTH", "month_utc", dateTime.monthOfYear().getAsString());
            }
            if (wantWeekOfWeekYearUTC) {
                parsable.addDissection(inputname, "TIME.WEEK", "weekofweekyear_utc",
                        dateTime.weekOfWeekyear().getAsString());
            }
            if (wantWeekYearUTC) {
                parsable.addDissection(inputname, "TIME.YEAR", "weekyear_utc", dateTime.weekyear().getAsString());
            }
            if (wantYearUTC) {
                parsable.addDissection(inputname, "TIME.YEAR", "year_utc", dateTime.year().getAsString());
            }
            if (wantHourUTC) {
                parsable.addDissection(inputname, "TIME.HOUR", "hour_utc", dateTime.hourOfDay().getAsString());
            }
            if (wantMinuteUTC) {
                parsable.addDissection(inputname, "TIME.MINUTE", "minute_utc",
                        dateTime.minuteOfHour().getAsString());
            }
            if (wantSecondUTC) {
                parsable.addDissection(inputname, "TIME.SECOND", "second_utc",
                        dateTime.secondOfMinute().getAsString());
            }
            if (wantMillisecondUTC) {
                parsable.addDissection(inputname, "TIME.MILLISECOND", "millisecond_utc",
                        dateTime.millisOfSecond().getAsString());
            }
        }
    }

    // --------------------------------------------

}