/* * Lilith - a log event viewer. * Copyright (C) 2007-2016 Joern Huxhorn * * 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 de.huxhorn.lilith.conditions; import de.huxhorn.lilith.data.access.AccessEvent; import de.huxhorn.lilith.data.eventsource.EventWrapper; import de.huxhorn.lilith.data.eventsource.LoggerContext; import de.huxhorn.lilith.data.logging.ExtendedStackTraceElement; import de.huxhorn.lilith.data.logging.LoggingEvent; import de.huxhorn.lilith.data.logging.Marker; import de.huxhorn.lilith.data.logging.Message; import de.huxhorn.lilith.data.logging.ThreadInfo; import de.huxhorn.lilith.data.logging.ThrowableInfo; import java.io.IOException; import java.io.ObjectInputStream; import java.util.HashSet; import java.util.IdentityHashMap; import java.util.Map; import java.util.Set; public class EventContainsCondition implements LilithCondition, SearchStringCondition { private static final long serialVersionUID = -8094852331877521764L; public static final String DESCRIPTION = "event.contains"; private String searchString; public EventContainsCondition() { this(null); } public EventContainsCondition(String searchString) { setSearchString(searchString); } public void setSearchString(String searchString) { this.searchString = searchString; } public String getSearchString() { return searchString; } private boolean checkString(String input) { if(input != null) { if(input.contains(searchString)) { return true; } } return false; } public boolean isTrue(Object value) { if(searchString == null) { return false; } if(searchString.length() == 0) { return true; } if(value instanceof EventWrapper) { EventWrapper wrapper = (EventWrapper) value; Object eventObj = wrapper.getEvent(); if(eventObj instanceof LoggingEvent) { LoggingEvent event = (LoggingEvent) eventObj; { String message = null; Message messageObj = event.getMessage(); if(messageObj != null) { message = messageObj.getMessage(); } if(message != null) { if(checkString(message)) { return true; } } } { if (checkLoggerContext(event.getLoggerContext())) { return true; } } { String level = "" + event.getLevel(); if(checkString(level)) { return true; } } { String loggerName = event.getLogger(); if(checkString(loggerName)) { return true; } } { if(checkStackTraceElements(event.getCallStack())) { return true; } } { ThrowableInfo throwable = event.getThrowable(); if(checkThrowable(throwable, null)) { return true; } } { ThreadInfo threadInfo = event.getThreadInfo(); if(threadInfo != null) { if(checkString(threadInfo.getName())) { return true; } Long threadId = threadInfo.getId(); if(threadId != null) { if(checkString(Long.toString(threadId))) { return true; } } Integer threadPriority = threadInfo.getPriority(); if(threadPriority != null) { if(checkString(Integer.toString(threadPriority))) { return true; } } if(checkString(threadInfo.getGroupName())) { return true; } Long groupId = threadInfo.getGroupId(); if(groupId != null) { if(checkString(Long.toString(groupId))) { return true; } } } } { Map<String, String> mdcMap = event.getMdc(); if(checkMap(mdcMap)) { return true; } } { if(checkMarker(event.getMarker(), null)) { return true; } } { Message[] ndc = event.getNdc(); if(ndc != null) { for (Message current : ndc) { if(current == null) { continue; } if(checkString(current.getMessage())) { return true; } if(checkString(current.getMessagePattern())) { return true; } } } } } else if(eventObj instanceof AccessEvent) { AccessEvent event = (AccessEvent) eventObj; { String message = event.getRequestURL(); if(checkString(message)) { return true; } } { if (checkLoggerContext(event.getLoggerContext())) { return true; } } { String message = "" + event.getStatusCode(); if(checkString(message)) { return true; } } { Map<String, String> propertyMap = event.getRequestHeaders(); if(checkMap(propertyMap)) { return true; } } { Map<String, String> propertyMap = event.getResponseHeaders(); if(checkMap(propertyMap)) { return true; } } { Map<String, String[]> propertyMap = event.getRequestParameters(); if(checkArrayMap(propertyMap)) { return true; } } } } return false; } private boolean checkLoggerContext(LoggerContext context) { if (context == null) { return false; } return checkString(context.getName()) || checkMap(context.getProperties()); } private boolean checkThrowable(ThrowableInfo throwable, IdentityHashMap<ThrowableInfo, Object> dejaVu) { if(throwable == null) { return false; } if(dejaVu == null) { dejaVu = new IdentityHashMap<>(); } if(dejaVu.containsKey(throwable)) { return false; } dejaVu.put(throwable, null); if(checkString(throwable.getName())) { return true; } if(checkString(throwable.getMessage())) { return true; } if(checkThrowable(throwable.getCause(), dejaVu)) { return true; } ThrowableInfo[] suppressed = throwable.getSuppressed(); if(suppressed != null) { for (ThrowableInfo current : suppressed) { if(checkThrowable(current, dejaVu)) { return true; } } } return checkStackTraceElements(throwable.getStackTrace()); } private boolean checkStackTraceElements(ExtendedStackTraceElement[] callStack) { if(callStack == null) { return false; } for (ExtendedStackTraceElement current : callStack) { if(current == null) { continue; } if(checkString(current.toString(true))) { return true; } } return false; } private boolean checkMarker(Marker marker, Set<String> processedMarkers) { if(marker == null) { return false; } if(checkString(marker.getName())) { return true; } if(processedMarkers == null) { processedMarkers = new HashSet<>(); } if(!processedMarkers.contains(marker.getName())) { processedMarkers.add(marker.getName()); if(marker.hasReferences()) { Map<String, Marker> children = marker.getReferences(); for(Map.Entry<String, Marker> current : children.entrySet()) { if(checkMarker(current.getValue(), processedMarkers)) { return true; } } } } return false; } private boolean checkMap(Map<String, String> map) { if(map == null) { return false; } for(Map.Entry<String, String> entry : map.entrySet()) { if(checkString(entry.getKey()) || checkString(entry.getValue())) { return true; } } return false; } private boolean checkArrayMap(Map<String, String[]> map) { if(map == null) { return false; } for(Map.Entry<String, String[]> entry : map.entrySet()) { if(checkString(entry.getKey())) { return true; } String[] array = entry.getValue(); if(array == null) { continue; } for(String s : array) { if(checkString(s)) { return true; } } } return false; } private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { in.defaultReadObject(); setSearchString(this.searchString); } public boolean equals(Object o) { if(this == o) return true; if(o == null || getClass() != o.getClass()) return false; EventContainsCondition that = (EventContainsCondition) o; return !(searchString != null ? !searchString.equals(that.searchString) : that.searchString != null); } public int hashCode() { int result; result = (searchString != null ? searchString.hashCode() : 0); return result; } public EventContainsCondition clone() throws CloneNotSupportedException { return (EventContainsCondition) super.clone(); } public String toString() { StringBuilder result = new StringBuilder(); result.append(getDescription()).append("("); if(searchString != null) { result.append("\""); result.append(searchString); result.append("\""); } else { result.append("null"); } result.append(")"); return result.toString(); } public String getDescription() { return DESCRIPTION; } }