@Test public void testSlashInFormat() { FormatDateTimeFormatter formatter = Joda.forPattern("MM/yyyy"); formatter.parser().parseMillis("01/2001"); formatter = Joda.forPattern("yyyy/MM/dd HH:mm:ss"); long millis = formatter.parser().parseMillis("1970/01/01 00:00:00"); formatter.printer().print(millis); try { millis = formatter.parser().parseMillis("1970/01/01"); assert false; } catch (IllegalArgumentException e) { // it really can't parse this one } }
private void expectInvalidPattern(String pattern, String errorMessage) { try { Joda.forPattern(pattern); fail("Pattern " + pattern + " should have thrown an exception but did not"); } catch (IllegalArgumentException e) { assertThat(e.getMessage(), containsString(errorMessage)); } }
public static class Defaults { public static final FormatDateTimeFormatter[] DYNAMIC_DATE_TIME_FORMATTERS = new FormatDateTimeFormatter[] { DateFieldMapper.Defaults.DATE_TIME_FORMATTER, Joda.forPattern("yyyy/MM/dd HH:mm:ss||yyyy/MM/dd") }; public static final boolean DATE_DETECTION = true; public static final boolean NUMERIC_DETECTION = false; }
public void fromXContent(XContentParser parser) throws IOException { DateMathParser dateParser = new DateMathParser(Joda.forPattern("dateOptionalTime"), TimeUnit.MILLISECONDS); String currentFieldName = null; XContentParser.Token token; while ((token = parser.nextToken()) != END_OBJECT) { if (token == null) { break; } else if (token == FIELD_NAME) { currentFieldName = parser.currentName(); } else if (token == VALUE_NULL || token == VALUE_STRING || token == VALUE_BOOLEAN || token == VALUE_NUMBER) { if (currentFieldName.equals("name")) { setName(parser.text()); } else if (currentFieldName.equals("type")) { setType(parser.text()); } else if (currentFieldName.equals("started")) { try { this.started = new Date(dateParser.parse(parser.text(), 0)); } catch (Exception e) { // ignore } } else if (currentFieldName.equals("timestamp")) { try { setTimestamp(new Date(dateParser.parse(parser.text(), 0))); } catch (Exception e) { // ignore } } else if (currentFieldName.equals("counter")) { try { setCounter(parser.longValue()); } catch (Exception e) { // ignore } } else if (currentFieldName.equals("enabled")) { setEnabled(parser.booleanValue()); } else if (currentFieldName.equals("active")) { setActive(parser.booleanValue()); } } else if (token == START_OBJECT) { if ("custom".equals(currentFieldName)) { setCustom(parser.map()); } } } }
public static class Defaults extends NumberFieldMapper.Defaults { public static final FormatDateTimeFormatter DATE_TIME_FORMATTER = Joda.forPattern("dateOptionalTime", Locale.ROOT); public static final FieldType FIELD_TYPE = new FieldType(NumberFieldMapper.Defaults.FIELD_TYPE); static { FIELD_TYPE.freeze(); } public static final String NULL_VALUE = null; public static final TimeUnit TIME_UNIT = TimeUnit.MILLISECONDS; }
@Test public void testIsoVsCustom() { DateTimeFormatter formatter = ISODateTimeFormat.dateOptionalTimeParser().withZone(DateTimeZone.UTC); long millis = formatter.parseMillis("1970-01-01T00:00:00"); assertThat(millis, equalTo(0l)); formatter = DateTimeFormat.forPattern("yyyy/MM/dd HH:mm:ss").withZone(DateTimeZone.UTC); millis = formatter.parseMillis("1970/01/01 00:00:00"); assertThat(millis, equalTo(0l)); FormatDateTimeFormatter formatter2 = Joda.forPattern("yyyy/MM/dd HH:mm:ss"); millis = formatter2.parser().parseMillis("1970/01/01 00:00:00"); assertThat(millis, equalTo(0l)); }
@Test public void testMultipleDifferentFormats() { FormatDateTimeFormatter formatter = Joda.forPattern("yyyy/MM/dd HH:mm:ss||yyyy/MM/dd"); String input = "1970/01/01 00:00:00"; long millis = formatter.parser().parseMillis(input); assertThat(input, is(formatter.printer().print(millis))); Joda.forPattern("yyyy/MM/dd HH:mm:ss||yyyy/MM/dd||dateOptionalTime"); Joda.forPattern("dateOptionalTime||yyyy/MM/dd HH:mm:ss||yyyy/MM/dd"); Joda.forPattern("yyyy/MM/dd HH:mm:ss||dateOptionalTime||yyyy/MM/dd"); Joda.forPattern("date_time||date_time_no_millis"); Joda.forPattern(" date_time || date_time_no_millis"); }
public static FormatDateTimeFormatter parseDateTimeFormatter(Object node) { return Joda.forPattern(node.toString()); }
@Test public void testMultipleFormats() { FormatDateTimeFormatter formatter = Joda.forPattern("yyyy/MM/dd HH:mm:ss||yyyy/MM/dd"); long millis = formatter.parser().parseMillis("1970/01/01 00:00:00"); assertThat("1970/01/01 00:00:00", is(formatter.printer().print(millis))); }
public class HotThreads { private static final Object mutex = new Object(); private static final FormatDateTimeFormatter DATE_TIME_FORMATTER = Joda.forPattern("dateOptionalTime"); private int busiestThreads = 3; private TimeValue interval = new TimeValue(500, TimeUnit.MILLISECONDS); private TimeValue threadElementsSnapshotDelay = new TimeValue(10); private int threadElementsSnapshotCount = 10; private String type = "cpu"; private boolean ignoreIdleThreads = true; public HotThreads interval(TimeValue interval) { this.interval = interval; return this; } public HotThreads busiestThreads(int busiestThreads) { this.busiestThreads = busiestThreads; return this; } public HotThreads ignoreIdleThreads(boolean ignoreIdleThreads) { this.ignoreIdleThreads = ignoreIdleThreads; return this; } public HotThreads threadElementsSnapshotDelay(TimeValue threadElementsSnapshotDelay) { this.threadElementsSnapshotDelay = threadElementsSnapshotDelay; return this; } public HotThreads threadElementsSnapshotCount(int threadElementsSnapshotCount) { this.threadElementsSnapshotCount = threadElementsSnapshotCount; return this; } public HotThreads type(String type) { if ("cpu".equals(type) || "wait".equals(type) || "block".equals(type)) { this.type = type; } else { throw new IllegalArgumentException("type not supported [" + type + "]"); } return this; } public String detect() throws Exception { synchronized (mutex) { return innerDetect(); } } private static boolean isIdleThread(ThreadInfo threadInfo) { String threadName = threadInfo.getThreadName(); // NOTE: these are likely JVM dependent if (threadName.equals("Signal Dispatcher") || threadName.equals("Finalizer") || threadName.equals("Reference Handler")) { return true; } for (StackTraceElement frame : threadInfo.getStackTrace()) { String className = frame.getClassName(); String methodName = frame.getMethodName(); if (className.equals("java.util.concurrent.ThreadPoolExecutor") && methodName.equals("getTask")) { return true; } if (className.equals("sun.nio.ch.SelectorImpl") && methodName.equals("select")) { return true; } if (className.equals("org.elasticsearch.threadpool.ThreadPool$EstimatedTimeThread") && methodName.equals("run")) { return true; } if (className.equals("org.elasticsearch.indices.ttl.IndicesTTLService$Notifier") && methodName.equals("await")) { return true; } if (className.equals("java.util.concurrent.LinkedTransferQueue") && methodName.equals("poll")) { return true; } } return false; } private String innerDetect() throws Exception { StringBuilder sb = new StringBuilder(); sb.append("Hot threads at "); sb.append(DATE_TIME_FORMATTER.printer().print(System.currentTimeMillis())); sb.append(", interval="); sb.append(interval); sb.append(", busiestThreads="); sb.append(busiestThreads); sb.append(", ignoreIdleThreads="); sb.append(ignoreIdleThreads); sb.append(":\n"); ThreadMXBean threadBean = ManagementFactory.getThreadMXBean(); boolean enabledCpu = false; try { if (threadBean.isThreadCpuTimeSupported()) { if (!threadBean.isThreadCpuTimeEnabled()) { enabledCpu = true; threadBean.setThreadCpuTimeEnabled(true); } } else { throw new IllegalStateException("MBean doesn't support thread CPU Time"); } Map<Long, MyThreadInfo> threadInfos = new HashMap<>(); for (long threadId : threadBean.getAllThreadIds()) { // ignore our own thread... if (Thread.currentThread().getId() == threadId) { continue; } long cpu = threadBean.getThreadCpuTime(threadId); if (cpu == -1) { continue; } ThreadInfo info = threadBean.getThreadInfo(threadId, 0); if (info == null) { continue; } threadInfos.put(threadId, new MyThreadInfo(cpu, info)); } Thread.sleep(interval.millis()); for (long threadId : threadBean.getAllThreadIds()) { // ignore our own thread... if (Thread.currentThread().getId() == threadId) { continue; } long cpu = threadBean.getThreadCpuTime(threadId); if (cpu == -1) { threadInfos.remove(threadId); continue; } ThreadInfo info = threadBean.getThreadInfo(threadId, 0); if (info == null) { threadInfos.remove(threadId); continue; } MyThreadInfo data = threadInfos.get(threadId); if (data != null) { data.setDelta(cpu, info); } else { threadInfos.remove(threadId); } } // sort by delta CPU time on thread. List<MyThreadInfo> hotties = new ArrayList<>(threadInfos.values()); final int busiestThreads = Math.min(this.busiestThreads, hotties.size()); // skip that for now CollectionUtil.introSort( hotties, new Comparator<MyThreadInfo>() { @Override public int compare(MyThreadInfo o1, MyThreadInfo o2) { if ("cpu".equals(type)) { return (int) (o2.cpuTime - o1.cpuTime); } else if ("wait".equals(type)) { return (int) (o2.waitedTime - o1.waitedTime); } else if ("block".equals(type)) { return (int) (o2.blockedTime - o1.blockedTime); } throw new IllegalArgumentException(); } }); // analyse N stack traces for M busiest threads long[] ids = new long[busiestThreads]; for (int i = 0; i < busiestThreads; i++) { MyThreadInfo info = hotties.get(i); ids[i] = info.info.getThreadId(); } ThreadInfo[][] allInfos = new ThreadInfo[threadElementsSnapshotCount][]; for (int j = 0; j < threadElementsSnapshotCount; j++) { // NOTE, javadoc of getThreadInfo says: If a thread of the given ID is not alive or does not // exist, // null will be set in the corresponding element in the returned array. A thread is alive if // it has // been started and has not yet died. allInfos[j] = threadBean.getThreadInfo(ids, Integer.MAX_VALUE); Thread.sleep(threadElementsSnapshotDelay.millis()); } for (int t = 0; t < busiestThreads; t++) { long time = 0; if ("cpu".equals(type)) { time = hotties.get(t).cpuTime; } else if ("wait".equals(type)) { time = hotties.get(t).waitedTime; } else if ("block".equals(type)) { time = hotties.get(t).blockedTime; } String threadName = null; for (ThreadInfo[] info : allInfos) { if (info != null && info[t] != null) { if (ignoreIdleThreads && isIdleThread(info[t])) { info[t] = null; continue; } threadName = info[t].getThreadName(); break; } } if (threadName == null) { continue; // thread is not alive yet or died before the first snapshot - ignore it! } double percent = (((double) time) / interval.nanos()) * 100; sb.append( String.format( Locale.ROOT, "%n%4.1f%% (%s out of %s) %s usage by thread '%s'%n", percent, TimeValue.timeValueNanos(time), interval, type, threadName)); // for each snapshot (2nd array index) find later snapshot for same thread with max number // of // identical StackTraceElements (starting from end of each) boolean[] done = new boolean[threadElementsSnapshotCount]; for (int i = 0; i < threadElementsSnapshotCount; i++) { if (done[i]) continue; int maxSim = 1; boolean[] similars = new boolean[threadElementsSnapshotCount]; for (int j = i + 1; j < threadElementsSnapshotCount; j++) { if (done[j]) continue; int similarity = similarity(allInfos[i][t], allInfos[j][t]); if (similarity > maxSim) { maxSim = similarity; similars = new boolean[threadElementsSnapshotCount]; } if (similarity == maxSim) similars[j] = true; } // print out trace maxSim levels of i, and mark similar ones as done int count = 1; for (int j = i + 1; j < threadElementsSnapshotCount; j++) { if (similars[j]) { done[j] = true; count++; } } if (allInfos[i][t] != null) { final StackTraceElement[] show = allInfos[i][t].getStackTrace(); if (count == 1) { sb.append(String.format(Locale.ROOT, " unique snapshot%n")); for (int l = 0; l < show.length; l++) { sb.append(String.format(Locale.ROOT, " %s%n", show[l])); } } else { sb.append( String.format( Locale.ROOT, " %d/%d snapshots sharing following %d elements%n", count, threadElementsSnapshotCount, maxSim)); for (int l = show.length - maxSim; l < show.length; l++) { sb.append(String.format(Locale.ROOT, " %s%n", show[l])); } } } } } return sb.toString(); } finally { if (enabledCpu) { threadBean.setThreadCpuTimeEnabled(false); } } } private static final StackTraceElement[] EMPTY = new StackTraceElement[0]; private int similarity(ThreadInfo threadInfo, ThreadInfo threadInfo0) { StackTraceElement[] s1 = threadInfo == null ? EMPTY : threadInfo.getStackTrace(); StackTraceElement[] s2 = threadInfo0 == null ? EMPTY : threadInfo0.getStackTrace(); int i = s1.length - 1; int j = s2.length - 1; int rslt = 0; while (i >= 0 && j >= 0 && s1[i].equals(s2[j])) { rslt++; i--; j--; } return rslt; } class MyThreadInfo { long cpuTime; long blockedCount; long blockedTime; long waitedCount; long waitedTime; boolean deltaDone; ThreadInfo info; MyThreadInfo(long cpuTime, ThreadInfo info) { blockedCount = info.getBlockedCount(); blockedTime = info.getBlockedTime(); waitedCount = info.getWaitedCount(); waitedTime = info.getWaitedTime(); this.cpuTime = cpuTime; this.info = info; } void setDelta(long cpuTime, ThreadInfo info) { if (deltaDone) throw new IllegalStateException("setDelta already called once"); blockedCount = info.getBlockedCount() - blockedCount; blockedTime = info.getBlockedTime() - blockedTime; waitedCount = info.getWaitedCount() - waitedCount; waitedTime = info.getWaitedTime() - waitedTime; this.cpuTime = cpuTime - this.cpuTime; deltaDone = true; this.info = info; } } }