001/** 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018 019 020package org.apache.oozie.util; 021 022import java.io.IOException; 023import java.text.ParseException; 024import java.text.SimpleDateFormat; 025import java.util.Date; 026import java.util.HashSet; 027import java.util.Map; 028 029import org.apache.commons.lang.StringUtils; 030import org.apache.oozie.ErrorCode; 031import org.apache.oozie.client.rest.RestConstants; 032import org.apache.oozie.command.CommandException; 033 034public class XLogUserFilterParam { 035 036 public static final String START_TIME = "START"; 037 038 public static final String END_TIME = "END"; 039 040 public static final String SEARCH_TEXT = "TEXT"; 041 042 public static final String LOG_LEVEL = "LOGLEVEL"; 043 044 public static final String LIMIT = "LIMIT"; 045 046 public static final String RECENT_LOG_OFFSET = "RECENT"; 047 048 public static final String DEBUG = "DEBUG"; 049 050 private Date startTime; 051 private Date endTime; 052 private int startOffset; 053 private int endOffset = -1; 054 private int recent = -1; 055 private String logLevel; 056 private int limit = -1; 057 private boolean isDebug = false; 058 private String searchText; 059 060 private String params; 061 062 public static final ThreadLocal<SimpleDateFormat> dt = new ThreadLocal<SimpleDateFormat>() { 063 @Override 064 protected SimpleDateFormat initialValue() { 065 return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 066 } 067 }; 068 069 static final HashSet<String> LOG_LEVELS = new HashSet<String>(); 070 static { 071 LOG_LEVELS.add("ALL"); 072 LOG_LEVELS.add("DEBUG"); 073 LOG_LEVELS.add("ERROR"); 074 LOG_LEVELS.add("INFO"); 075 LOG_LEVELS.add("TRACE"); 076 LOG_LEVELS.add("WARN"); 077 LOG_LEVELS.add("FATAL"); 078 } 079 080 public XLogUserFilterParam() { 081 } 082 083 /** 084 * Instantiates a new log user param. 085 * 086 * @param params the params 087 * @throws CommandException the command exception 088 */ 089 public XLogUserFilterParam(Map<String, String[]> params) throws CommandException { 090 if (params != null && params.get(RestConstants.LOG_FILTER_OPTION) != null 091 && params.get(RestConstants.LOG_FILTER_OPTION).length > 0) { 092 try { 093 parseFilterParam(params.get(RestConstants.LOG_FILTER_OPTION)[0]); 094 } 095 catch (Exception e) { 096 throw new CommandException(ErrorCode.E0302, e.getMessage()); 097 098 } 099 } 100 } 101 102 /** 103 * Parse filter param 104 * 105 * @param param the param 106 * @throws Exception 107 */ 108 private void parseFilterParam(String param) throws Exception { 109 this.params = param; 110 111 if (StringUtils.isEmpty(param) || StringUtils.equalsIgnoreCase(param, "null")) { 112 return; 113 } 114 for (String keyValue : param.split(";")) { 115 String[] pairs = keyValue.split("="); 116 String key = pairs[0].toUpperCase(); 117 String value = pairs.length == 1 ? "" : pairs[1]; 118 if (key.equals(START_TIME)) { 119 startTime = getDate(value); 120 if (startTime == null) { 121 startOffset = getOffsetInMinute(value); 122 } 123 } 124 else if (key.equals(END_TIME)) { 125 endTime = getDate(value); 126 if (endTime == null) { 127 endOffset = getOffsetInMinute(value); 128 } 129 130 } 131 else if (key.equals(RECENT_LOG_OFFSET)) { 132 recent = getOffsetInMinute(value); 133 } 134 else if (key.equals(LIMIT)) { 135 limit = Integer.parseInt(value); 136 137 } 138 else if (key.equals(LOG_LEVEL)) { 139 logLevel = value; 140 validateLogLevel(logLevel); 141 142 } 143 else if (key.equals(DEBUG)) { 144 isDebug = true; 145 146 } 147 else if (key.equals(SEARCH_TEXT)) { 148 searchText = value; 149 150 } 151 else { 152 throw new Exception("Unsupported log filter " + key); 153 } 154 } 155 } 156 157 /** 158 * Gets the log level. 159 * 160 * @return the log level 161 */ 162 public String getLogLevel() { 163 return logLevel; 164 165 } 166 167 /** 168 * Gets the start date. 169 * 170 * @return the start date 171 */ 172 public Date getStartDate() { 173 return startTime; 174 } 175 176 /** 177 * Gets the end date. 178 * 179 * @return the end date 180 */ 181 public Date getEndDate() { 182 return endTime; 183 } 184 185 /** 186 * Gets the search text. 187 * 188 * @return the search text 189 */ 190 public String getSearchText() { 191 return searchText; 192 } 193 194 /** 195 * Validate log level. 196 * 197 * @param loglevel the log level to validate 198 * @throws CommandException in case of a non-supported log level. 199 */ 200 public void validateLogLevel(String loglevel) throws CommandException { 201 if (StringUtils.isEmpty(loglevel)) { 202 return; 203 } 204 for (String level : getLogLevel().split("\\|")) { 205 if (!LOG_LEVELS.contains(level)) { 206 throw new CommandException(ErrorCode.E0302, "Supported log level are " + LOG_LEVELS.toString()); 207 } 208 } 209 } 210 211 /** 212 * Validate search text. 213 * 214 * @throws CommandException the command exception 215 */ 216 public void validateSearchText() throws CommandException { 217 // No restriction on search text. 218 219 } 220 221 /** 222 * Gets the date. Date can in TZ or yyyy-MM-dd HH:mm:ss,SSS format 223 * 224 * @param date date 225 * @return the date 226 */ 227 public Date getDate(String date) { 228 try { 229 return DateUtils.parseDateOozieTZ(date); 230 } 231 catch (ParseException e) { 232 try { 233 return dt.get().parse(date); 234 } 235 catch (ParseException e1) { 236 return null; 237 } 238 } 239 } 240 241 /** 242 * Checks if is debug. 243 * 244 * @return true, if it's debug 245 */ 246 public boolean isDebug() { 247 return isDebug; 248 } 249 250 public Date getEndTime() { 251 return endTime; 252 } 253 254 public int getEndOffset() { 255 return endOffset; 256 } 257 258 public int getRecent() { 259 return recent; 260 } 261 262 public int getLimit() { 263 return limit; 264 } 265 266 public int getStartOffset() { 267 return startOffset; 268 } 269 270 @Override 271 public String toString() { 272 return params; 273 } 274 275 private int getOffsetInMinute(String offset) throws IOException { 276 277 if (Character.isLetter(offset.charAt(offset.length() - 1))) { 278 switch (offset.charAt(offset.length() - 1)) { 279 case 'h': 280 return Integer.parseInt(offset.substring(0, offset.length() - 1)) * 60; 281 case 'm': 282 return Integer.parseInt(offset.substring(0, offset.length() - 1)); 283 default: 284 throw new IOException("Unsupported offset " + offset); 285 } 286 } 287 else { 288 if (StringUtils.isNumeric(offset)) { 289 return Integer.parseInt(offset) * 60; 290 } 291 else { 292 throw new IOException("Unsupported time : " + offset); 293 } 294 } 295 } 296 297}