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 019package org.apache.oozie.util; 020 021import java.io.IOException; 022import java.text.ParseException; 023import java.text.SimpleDateFormat; 024import java.util.Date; 025import java.util.HashSet; 026import java.util.Map; 027 028import org.apache.commons.lang.StringUtils; 029import org.apache.oozie.ErrorCode; 030import org.apache.oozie.client.rest.RestConstants; 031import org.apache.oozie.command.CommandException; 032 033public class XLogUserFilterParam { 034 035 public static final String START_TIME = "START"; 036 037 public static final String END_TIME = "END"; 038 039 public static final String SEARCH_TEXT = "TEXT"; 040 041 public static final String LOG_LEVEL = "LOGLEVEL"; 042 043 public static final String LIMIT = "LIMIT"; 044 045 public static final String RECENT_LOG_OFFSET = "RECENT"; 046 047 public static final String DEBUG = "DEBUG"; 048 049 private Date startTime; 050 private Date endTime; 051 private int startOffset; 052 private int endOffset = -1; 053 private int recent = -1; 054 private String logLevel; 055 private int limit = -1; 056 private boolean isDebug = false; 057 private String searchText; 058 059 private String params; 060 061 public static final ThreadLocal<SimpleDateFormat> dt = new ThreadLocal<SimpleDateFormat>() { 062 @Override 063 protected SimpleDateFormat initialValue() { 064 return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 065 } 066 }; 067 068 static final HashSet<String> LOG_LEVELS = new HashSet<String>(); 069 static { 070 LOG_LEVELS.add("ALL"); 071 LOG_LEVELS.add("DEBUG"); 072 LOG_LEVELS.add("ERROR"); 073 LOG_LEVELS.add("INFO"); 074 LOG_LEVELS.add("TRACE"); 075 LOG_LEVELS.add("WARN"); 076 LOG_LEVELS.add("FATAL"); 077 } 078 079 public XLogUserFilterParam() { 080 } 081 082 /** 083 * Instantiates a new log user param. 084 * 085 * @param params the params 086 * @throws CommandException the command exception 087 */ 088 public XLogUserFilterParam(Map<String, String[]> params) throws CommandException { 089 if (params != null && params.get(RestConstants.LOG_FILTER_OPTION) != null 090 && params.get(RestConstants.LOG_FILTER_OPTION).length > 0) { 091 try { 092 parseFilterParam(params.get(RestConstants.LOG_FILTER_OPTION)[0]); 093 } 094 catch (Exception e) { 095 throw new CommandException(ErrorCode.E0302, e.getMessage()); 096 097 } 098 } 099 } 100 101 /** 102 * Parse filter param 103 * 104 * @param param the param 105 * @param map the map 106 * @throws Exception 107 */ 108 private void parseFilterParam(String param) throws Exception { 109 this.params = param; 110 111 if (StringUtils.isEmpty(param)) { 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 * @throws CommandException 198 */ 199 public void validateLogLevel(String loglevel) throws CommandException { 200 if (StringUtils.isEmpty(loglevel)) { 201 return; 202 } 203 for (String level : getLogLevel().split("\\|")) { 204 if (!LOG_LEVELS.contains(level)) { 205 throw new CommandException(ErrorCode.E0302, "Supported log level are " + LOG_LEVELS.toString()); 206 } 207 } 208 } 209 210 /** 211 * Validate search text. 212 * 213 * @throws CommandException the command exception 214 */ 215 public void validateSearchText() throws CommandException { 216 // No restriction on search text. 217 218 } 219 220 /** 221 * Gets the date. Date can in TZ or yyyy-MM-dd HH:mm:ss,SSS format 222 * 223 * @param String date 224 * @return the date 225 */ 226 public Date getDate(String date) { 227 try { 228 return DateUtils.parseDateOozieTZ(date); 229 } 230 catch (ParseException e) { 231 try { 232 return dt.get().parse(date); 233 } 234 catch (ParseException e1) { 235 return null; 236 } 237 } 238 } 239 240 /** 241 * Checks if is debug. 242 * 243 * @return true, if it's debug 244 */ 245 public boolean isDebug() { 246 return isDebug; 247 } 248 249 public Date getEndTime() { 250 return endTime; 251 } 252 253 public int getEndOffset() { 254 return endOffset; 255 } 256 257 public int getRecent() { 258 return recent; 259 } 260 261 public int getLimit() { 262 return limit; 263 } 264 265 public int getStartOffset() { 266 return startOffset; 267 } 268 269 @Override 270 public String toString() { 271 return params; 272 } 273 274 private int getOffsetInMinute(String offset) throws IOException { 275 276 if (Character.isLetter(offset.charAt(offset.length() - 1))) { 277 switch (offset.charAt(offset.length() - 1)) { 278 case 'H': 279 case 'h': 280 return Integer.parseInt(offset.substring(0, offset.length() - 1)) * 60; 281 case 'M': 282 case 'm': 283 return Integer.parseInt(offset.substring(0, offset.length() - 1)); 284 default: 285 throw new IOException("Unsupported offset " + offset); 286 } 287 } 288 else { 289 if (StringUtils.isNumeric(offset)) { 290 return Integer.parseInt(offset) * 60; 291 } 292 else { 293 throw new IOException("Unsupported time : " + offset); 294 } 295 } 296 } 297 298}