net.mikaboshi.intra_mart.tools.log_stats.parser.LineLogParser.java Source code

Java tutorial

Introduction

Here is the source code for net.mikaboshi.intra_mart.tools.log_stats.parser.LineLogParser.java

Source

/*
 * 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 net.mikaboshi.intra_mart.tools.log_stats.parser;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;

import net.mikaboshi.intra_mart.tools.log_stats.entity.Level;
import net.mikaboshi.intra_mart.tools.log_stats.entity.LogLayoutItemType;
import net.mikaboshi.intra_mart.tools.log_stats.entity.TransitionType;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;

/**
 * 
 *
 * @version 1.0.10
 * @author <a href="https://github.com/cwan">cwan</a>
 */
public abstract class LineLogParser extends GenericLogParser {

    private static final Pattern LOG_LAYOUT_PATTERN = Pattern
            .compile("^(%(?:\\-\\d+)?([a-zA-Z0-9\\.]+)(?:\\{(.+?)\\})?).*");

    /** ????? */
    private int nLine = 0;

    Pattern logLayoutPattern;

    private LayoutItem[] layoutItems;

    /** ?? */
    private final DateFormat requestAcceptTimeFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss,SSS");

    public LineLogParser(ParserParameter parameter, String layout) throws PatternSyntaxException {

        super(parameter);
        init(layout);
    }

    protected void init(String layout) {

        if (layout == null) {
            throw new NullPointerException();
        }

        List<LayoutItem> layoutItemList = new ArrayList<LineLogParser.LayoutItem>();

        StringBuilder sb = new StringBuilder();

        sb.append("^");

        int head = 0;

        while (head < layout.length()) {

            Matcher matcher = LOG_LAYOUT_PATTERN.matcher(layout.substring(head));

            if (matcher.matches()) {

                String name = matcher.group(2);
                String option = matcher.group(3);

                head += matcher.group(1).length();

                LayoutItem layoutItem = new LayoutItem();

                layoutItem.type = LogLayoutItemType.toEnum(name, option);

                if (layoutItem.type == null) {
                    throw new IllegalArgumentException("Illegal log layout name : " + name + "(" + option + ")");
                }

                if (layoutItem.type == LogLayoutItemType.NOPEX || layoutItem.type == LogLayoutItemType.NEW_LINE) {
                    // ????????
                    continue;
                }

                sb.append("(.*?)");

                if (layoutItem.type == LogLayoutItemType.DATE) {
                    layoutItem.dateFormat = new SimpleDateFormat(option);
                }

                layoutItemList.add(layoutItem);

            } else {

                char c = layout.charAt(head++);

                if (c == '\t') {
                    sb.append("\\t");

                } else if (c == '\\' || c == '[' || c == ']' || c == '^' || c == '$' || c == '-' || c == '&'
                        || c == '.' || c == '+' || c == '*' || c == '{' || c == '}' || c == ',' || c == '|'
                        || c == '(' || c == ')' || c == ':' || c == '=' || c == '<' || c == '>' || c == '!') {

                    sb.append("\\");
                    sb.append(c);

                } else {

                    sb.append(c);
                }
            }
        }

        sb.append("$");

        this.layoutItems = layoutItemList.toArray(new LayoutItem[layoutItemList.size()]);

        this.logLayoutPattern = Pattern.compile(sb.toString());
    }

    /**
     * 1?????Map??
     * ?????????null?
     * @param line
     * @return
     */
    protected Map<LogLayoutItemType, Object> parseLine(String line) {

        this.nLine++;

        if (line == null) {
            throw new IllegalArgumentException("line is null");
        }

        Matcher matcher = this.logLayoutPattern.matcher(line);

        if (!matcher.matches()) {
            warn("Unparsable line");
            this.parameter.getErrorCounter().increment();
            return null;
        }

        Map<LogLayoutItemType, Object> lineMap = new HashMap<LogLayoutItemType, Object>();

        for (int i = 0; i < this.layoutItems.length; i++) {

            LayoutItem item = this.layoutItems[i];
            String value = matcher.group(i + 1);

            if (value != null) {
                value = value.trim();
            }

            switch (item.type) {

            case DATE:

                try {
                    lineMap.put(item.type, item.dateFormat.parse(value));
                } catch (ParseException e) {
                    warn("Invalid date : %s", value);
                    this.parameter.getErrorCounter().increment();
                }

                break;

            case LEVEL:

                lineMap.put(item.type, Level.toEnum(value));
                break;

            case MDC_LOG_REPORT_SEQUENCE:

                try {
                    // V6???????
                    value = StringUtils.remove(value, ',');

                    lineMap.put(item.type, Integer.parseInt(value));
                } catch (NumberFormatException e) {
                    warn("Invalid integer : %s", value);
                    this.parameter.getErrorCounter().increment();
                }

                break;

            case MDC_REQUEST_PAGE_TIME:
            case MDC_TRANSITION_TIME_RESPONSE:

                try {
                    // V6???????
                    value = StringUtils.remove(value, ',');

                    lineMap.put(item.type, Long.parseLong(value));

                } catch (NumberFormatException e) {
                    warn("Invalid long : %s", value);
                    this.parameter.getErrorCounter().increment();
                }

                break;

            case MDC_REQUEST_ACCEPT_TIME:

                try {
                    lineMap.put(item.type, this.requestAcceptTimeFormat.parse(value));
                } catch (ParseException e) {
                    warn("Invalid request accept time : %s", value);
                    this.parameter.getErrorCounter().increment();
                }

                break;

            case MDC_TRANSITION_LOG_TYPE_ID:

                lineMap.put(item.type, TransitionType.toEnum(value));
                break;

            default:

                lineMap.put(item.type, value);
            }
        }

        return lineMap;
    }

    /**
     * ??
     * @param lineMap
     * @param log
     */
    protected static void populate(Map<LogLayoutItemType, Object> lineMap,
            net.mikaboshi.intra_mart.tools.log_stats.entity.Log log) {

        log.logger = (String) lineMap.get(LogLayoutItemType.LOGGER_NAME);
        log.date = (Date) lineMap.get(LogLayoutItemType.DATE);
        log.message = (String) lineMap.get(LogLayoutItemType.MESSAGE);
        log.level = (Level) lineMap.get(LogLayoutItemType.LEVEL);
        log.thread = (String) lineMap.get(LogLayoutItemType.THREAD);
        log.requestId = (String) lineMap.get(LogLayoutItemType.MDC_REQUEST_ID);
        log.logId = (String) lineMap.get(LogLayoutItemType.MDC_LOG_ID);

        Integer seq = (Integer) lineMap.get(LogLayoutItemType.MDC_LOG_REPORT_SEQUENCE);

        if (seq != null) {
            log.logReportSequence = seq;
        }

        log.logThreadGroup = (String) lineMap.get(LogLayoutItemType.MDC_LOG_THREAD_GROUP);
        log.clientSessionId = (String) lineMap.get(LogLayoutItemType.MDC_CLIENT_SESSION_ID);
    }

    /**
     * INFO??
     */
    @Override
    protected void info(String format, Object... args) {

        Log logger = getLogger();

        if (logger.isInfoEnabled()) {
            logger.info(String.format("[" + getLogFilePath() + "#" + this.nLine + "] " + format, args));
        }
    }

    /**
     * WARN??
     */
    @Override
    protected void warn(String format, Object... args) {

        Log logger = getLogger();

        if (logger.isWarnEnabled()) {
            logger.warn(String.format("[" + getLogFilePath() + "#" + this.nLine + "] " + format, args));
        }
    }

    private static class LayoutItem {
        LogLayoutItemType type = null;
        DateFormat dateFormat = null;
    }
}