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

Java tutorial

Introduction

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

Source

/*
 * Apache HTTPD logparsing made easy
 * Copyright (C) 2011-2016 Niels Basjes
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package nl.basjes.parse.httpdlog.dissectors;

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 java.util.ArrayList;
import java.util.EnumSet;
import java.util.List;
import java.util.Locale;

public class TimeStampDissector extends Dissector {

    // The default parser to what we find in the Apache httpd Logfiles
    //                                                            [05/Sep/2010:11:27:50 +0200]
    public static final String DEFAULT_APACHE_DATE_TIME_PATTERN = "dd/MMM/yyyy:HH:mm:ss ZZ";

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

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

    @SuppressWarnings("UnusedDeclaration")
    public TimeStampDissector() {
        setDateTimePattern(DEFAULT_APACHE_DATE_TIME_PATTERN);
    }

    public TimeStampDissector(String newDateTimePattern) {
        if (newDateTimePattern == null || newDateTimePattern.trim().isEmpty()) {
            setDateTimePattern(DEFAULT_APACHE_DATE_TIME_PATTERN);
        } else {
            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");

        result.add("TIME.DATE:date"); // yyyy-MM-dd
        result.add("TIME.TIME:time"); // HH:mm:ss

        // 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");

        result.add("TIME.DATE:date_utc"); // yyyy-MM-dd
        result.add("TIME.TIME:time_utc"); // HH:mm:ss

        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;
    private boolean wantDate = false;
    private boolean wantTime = 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;
    private boolean wantDateUTC = false;
    private boolean wantTimeUTC = 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;

        case "date":
            wantDate = true;
            return Casts.STRING_ONLY;

        case "time":
            wantTime = true;
            return Casts.STRING_ONLY;

        // 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;

        case "date_utc":
            wantDateUTC = true;
            return Casts.STRING_ONLY;

        case "time_utc":
            wantTimeUTC = true;
            return Casts.STRING_ONLY;

        default:
            return null;
        }
    }

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

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

        // Timezone independent
        wantAnyTZIndependent = wantTimezone || wantEpoch;

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

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

    private static final DateTimeFormatter ISO_DATE_FORMATTER = DateTimeFormat.forPattern("yyyy-MM-dd");
    private static final DateTimeFormatter ISO_TIME_FORMATTER = DateTimeFormat.forPattern("HH:mm:ss");

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

        fieldValue = fieldValue.toLowerCase(Locale.getDefault());

        if (wantAnyAsParsed || wantAnyTZIndependent) {
            // 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().get());
            }
            if (wantMonthname) {
                parsable.addDissection(inputname, "TIME.MONTHNAME", "monthname",
                        dateTime.monthOfYear().getAsText(Locale.getDefault()));
            }
            if (wantMonth) {
                parsable.addDissection(inputname, "TIME.MONTH", "month", dateTime.monthOfYear().get());
            }
            if (wantWeekOfWeekYear) {
                parsable.addDissection(inputname, "TIME.WEEK", "weekofweekyear", dateTime.weekOfWeekyear().get());
            }
            if (wantWeekYear) {
                parsable.addDissection(inputname, "TIME.YEAR", "weekyear", dateTime.weekyear().get());
            }
            if (wantYear) {
                parsable.addDissection(inputname, "TIME.YEAR", "year", dateTime.year().get());
            }
            if (wantHour) {
                parsable.addDissection(inputname, "TIME.HOUR", "hour", dateTime.hourOfDay().get());
            }
            if (wantMinute) {
                parsable.addDissection(inputname, "TIME.MINUTE", "minute", dateTime.minuteOfHour().get());
            }
            if (wantSecond) {
                parsable.addDissection(inputname, "TIME.SECOND", "second", dateTime.secondOfMinute().get());
            }
            if (wantMillisecond) {
                parsable.addDissection(inputname, "TIME.MILLISECOND", "millisecond",
                        dateTime.millisOfSecond().get());
            }
            if (wantDate) {
                parsable.addDissection(inputname, "TIME.DATE", "date", ISO_DATE_FORMATTER.print(dateTime));
            }

            if (wantTime) {
                parsable.addDissection(inputname, "TIME.TIME", "time", ISO_TIME_FORMATTER.print(dateTime));
            }

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

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

            if (wantDayUTC) {
                parsable.addDissection(inputname, "TIME.DAY", "day_utc", dateTime.dayOfMonth().get());
            }
            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().get());
            }
            if (wantWeekOfWeekYearUTC) {
                parsable.addDissection(inputname, "TIME.WEEK", "weekofweekyear_utc",
                        dateTime.weekOfWeekyear().get());
            }
            if (wantWeekYearUTC) {
                parsable.addDissection(inputname, "TIME.YEAR", "weekyear_utc", dateTime.weekyear().get());
            }
            if (wantYearUTC) {
                parsable.addDissection(inputname, "TIME.YEAR", "year_utc", dateTime.year().get());
            }
            if (wantHourUTC) {
                parsable.addDissection(inputname, "TIME.HOUR", "hour_utc", dateTime.hourOfDay().get());
            }
            if (wantMinuteUTC) {
                parsable.addDissection(inputname, "TIME.MINUTE", "minute_utc", dateTime.minuteOfHour().get());
            }
            if (wantSecondUTC) {
                parsable.addDissection(inputname, "TIME.SECOND", "second_utc", dateTime.secondOfMinute().get());
            }
            if (wantMillisecondUTC) {
                parsable.addDissection(inputname, "TIME.MILLISECOND", "millisecond_utc",
                        dateTime.millisOfSecond().get());
            }
            if (wantDateUTC) {
                parsable.addDissection(inputname, "TIME.DATE", "date_utc", ISO_DATE_FORMATTER.print(dateTime));
            }

            if (wantTimeUTC) {
                parsable.addDissection(inputname, "TIME.TIME", "time_utc", ISO_TIME_FORMATTER.print(dateTime));
            }

        }
    }

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

}