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 * @param map the map 107 * @throws Exception 108 */ 109 private void parseFilterParam(String param) throws Exception { 110 this.params = param; 111 112 if (StringUtils.isEmpty(param) || StringUtils.equalsIgnoreCase(param, "null")) { 113 return; 114 } 115 for (String keyValue : param.split(";")) { 116 String[] pairs = keyValue.split("="); 117 String key = pairs[0].toUpperCase(); 118 String value = pairs.length == 1 ? "" : pairs[1]; 119 if (key.equals(START_TIME)) { 120 startTime = getDate(value); 121 if (startTime == null) { 122 startOffset = getOffsetInMinute(value); 123 } 124 } 125 else if (key.equals(END_TIME)) { 126 endTime = getDate(value); 127 if (endTime == null) { 128 endOffset = getOffsetInMinute(value); 129 } 130 131 } 132 else if (key.equals(RECENT_LOG_OFFSET)) { 133 recent = getOffsetInMinute(value); 134 } 135 else if (key.equals(LIMIT)) { 136 limit = Integer.parseInt(value); 137 138 } 139 else if (key.equals(LOG_LEVEL)) { 140 logLevel = value; 141 validateLogLevel(logLevel); 142 143 } 144 else if (key.equals(DEBUG)) { 145 isDebug = true; 146 147 } 148 else if (key.equals(SEARCH_TEXT)) { 149 searchText = value; 150 151 } 152 else { 153 throw new Exception("Unsupported log filter " + key); 154 } 155 } 156 } 157 158 /** 159 * Gets the log level. 160 * 161 * @return the log level 162 */ 163 public String getLogLevel() { 164 return logLevel; 165 166 } 167 168 /** 169 * Gets the start date. 170 * 171 * @return the start date 172 */ 173 public Date getStartDate() { 174 return startTime; 175 } 176 177 /** 178 * Gets the end date. 179 * 180 * @return the end date 181 */ 182 public Date getEndDate() { 183 return endTime; 184 } 185 186 /** 187 * Gets the search text. 188 * 189 * @return the search text 190 */ 191 public String getSearchText() { 192 return searchText; 193 } 194 195 /** 196 * Validate log level. 197 * 198 * @throws CommandException 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}