/* Copyright (c) 2008-2009 HomeAway, Inc. * All rights reserved. http://www.perf4j.org * * 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 org.perf4j.helpers; import org.perf4j.StopWatch; import java.util.regex.MatchResult; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * This helper class is used to parse StopWatches from log message. * * @author Alex Devine */ public class StopWatchParser { /** * The default regex used to parse StopWatches from Strings. The following is true of the * capturing groups of this pattern: * <ol> * <li> The start time in milliseconds, parseable as a long * <li> The elapsed time in milliseconds, parseable as a long * <li> The tag name * <li> Optional, if not null the message text. * </ol> */ public static final String DEFAULT_MATCH_PATTERN = "start\\[(\\d+)\\] time\\[(\\d+)\\] tag\\[(.*?)\\](?: message\\[(.*?)\\])?"; /** * The regex Pattern object used to parse Strings. */ private Pattern pattern; /** * Creates a StopWatchParser that uses the DEFAULT_MATCH_PATTERN to parse StopWatch message strings. */ public StopWatchParser() { this(DEFAULT_MATCH_PATTERN); } /** * Creates a StopWatchParser that uses the specified regex pattern string to parse StopWatch message strings. * * @param matchPattern The regex pattern String to use to parse log messages * @throws java.util.regex.PatternSyntaxException * Thrown if matchPattern is not a valid regex pattern. */ public StopWatchParser(String matchPattern) { pattern = Pattern.compile(matchPattern); } /** * Gets the Pattern object used by this StopWatchParser to parse StopWatch message strings. * * @return The Pattern object. */ public Pattern getPattern() { return pattern; } /** * This method parses a StopWatch from the given message string. * * @param message The message to parse, which was likely created with the StopWatch stop, lap or toString methods. * @return The parsed StopWatch, or null if the StopWatch couldn't be parsed. */ public StopWatch parseStopWatch(String message) { MatchResult result = match(message); return (result != null) ? parseStopWatchFromLogMatch(result) : null; } /** * Gets the MatchResult object that is returned when the Pattern used by this parser matches the specified message. * * @param message The StopWatch message to parse. * @return The MatchResult from matching the message, or null if it didn't match. */ public MatchResult match(String message) { Matcher matcher = getPattern().matcher(message); return matcher.find() ? matcher.toMatchResult() : null; } /** * Helper method returns a new StopWatch from the MatchResult returned when a log messages matches. * * @param matchResult The regex match result * @return A new StopWatch that reflects the data from the match result. */ public StopWatch parseStopWatchFromLogMatch(MatchResult matchResult) { return new StopWatch(Long.parseLong(matchResult.group(1)) /*start time*/, Long.parseLong(matchResult.group(2)) /*elapsed time*/, matchResult.group(3) /*tag*/, matchResult.group(4) /*message, may be null*/); } /** * This method is intended to be used when you want to do a quick check of whether or not the specified string * is valid WITHOUT incurring the cost to do a full parse. Thus, importantly, if this method returns false, the * message is GUARANTEED to NOT be parseable, BUT THE CONVERSE IS NOT TRUE. That is, if the method returns true, * you must still call one of the parse or match methods to determine if the message is in fact truly parseable. * * @param message The message to test * @return false if the message is DEFINITELY not parseable, true if it potentially (but not definitely) could * be parsed. */ public boolean isPotentiallyValid(String message) { return message.startsWith("start"); } }