blob: dd5fc44f6d3fd4bdf56da8664d3e842892de79ae [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package org.apache.skywalking.oap.server.core.query;
import java.util.LinkedList;
import java.util.List;
import org.apache.skywalking.oap.server.core.Const;
import org.apache.skywalking.oap.server.core.UnexpectedException;
import org.apache.skywalking.oap.server.core.analysis.Downsampling;
import org.apache.skywalking.oap.server.core.query.entity.Step;
import org.joda.time.DateTime;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;
/**
* @author peng-yongsheng
*/
public enum DurationUtils {
INSTANCE;
private static final DateTimeFormatter YYYY_MM = DateTimeFormat.forPattern("yyyy-MM");
private static final DateTimeFormatter YYYY_MM_DD = DateTimeFormat.forPattern("yyyy-MM-dd");
private static final DateTimeFormatter YYYY_MM_DD_HH = DateTimeFormat.forPattern("yyyy-MM-dd HH");
private static final DateTimeFormatter YYYY_MM_DD_HHMM = DateTimeFormat.forPattern("yyyy-MM-dd HHmm");
private static final DateTimeFormatter YYYY_MM_DD_HHMMSS = DateTimeFormat.forPattern("yyyy-MM-dd HHmmss");
private static final DateTimeFormatter YYYYMM = DateTimeFormat.forPattern("yyyyMM");
private static final DateTimeFormatter YYYYMMDD = DateTimeFormat.forPattern("yyyyMMdd");
private static final DateTimeFormatter YYYYMMDDHH = DateTimeFormat.forPattern("yyyyMMddHH");
private static final DateTimeFormatter YYYYMMDDHHMM = DateTimeFormat.forPattern("yyyyMMddHHmm");
private static final DateTimeFormatter YYYYMMDDHHMMSS = DateTimeFormat.forPattern("yyyyMMddHHmmss");
public long exchangeToTimeBucket(String dateStr) {
dateStr = dateStr.replaceAll(Const.LINE, Const.EMPTY_STRING);
dateStr = dateStr.replaceAll(Const.SPACE, Const.EMPTY_STRING);
return Long.parseLong(dateStr);
}
public long startTimeDurationToSecondTimeBucket(Step step, String dateStr) {
long secondTimeBucket = 0;
switch (step) {
case MONTH:
secondTimeBucket = exchangeToTimeBucket(dateStr) * 100 * 100 * 100 * 100;
break;
case DAY:
secondTimeBucket = exchangeToTimeBucket(dateStr) * 100 * 100 * 100;
break;
case HOUR:
secondTimeBucket = exchangeToTimeBucket(dateStr) * 100 * 100;
break;
case MINUTE:
secondTimeBucket = exchangeToTimeBucket(dateStr) * 100;
break;
case SECOND:
secondTimeBucket = exchangeToTimeBucket(dateStr);
break;
}
return secondTimeBucket;
}
public long endTimeDurationToSecondTimeBucket(Step step, String dateStr) {
long secondTimeBucket = 0;
switch (step) {
case MONTH:
secondTimeBucket = (((exchangeToTimeBucket(dateStr) * 100 + 99) * 100 + 99) * 100 + 99) * 100 + 99;
break;
case DAY:
secondTimeBucket = ((exchangeToTimeBucket(dateStr) * 100 + 99) * 100 + 99) * 100 + 99;
break;
case HOUR:
secondTimeBucket = (exchangeToTimeBucket(dateStr) * 100 + 99) * 100 + 99;
break;
case MINUTE:
secondTimeBucket = exchangeToTimeBucket(dateStr) * 100 + 99;
break;
case SECOND:
secondTimeBucket = exchangeToTimeBucket(dateStr);
break;
}
return secondTimeBucket;
}
public long startTimeToTimestamp(Step step, String dateStr) {
switch (step) {
case MONTH:
return YYYY_MM.parseMillis(dateStr);
case DAY:
return YYYY_MM_DD.parseMillis(dateStr);
case HOUR:
return YYYY_MM_DD_HH.parseMillis(dateStr);
case MINUTE:
return YYYY_MM_DD_HHMM.parseMillis(dateStr);
case SECOND:
return YYYY_MM_DD_HHMMSS.parseMillis(dateStr);
}
throw new UnexpectedException("Unsupported step " + step.name());
}
public long endTimeToTimestamp(Step step, String dateStr) {
switch (step) {
case MONTH:
return YYYY_MM.parseDateTime(dateStr).plusMonths(1).getMillis();
case DAY:
return YYYY_MM_DD.parseDateTime(dateStr).plusDays(1).getMillis();
case HOUR:
return YYYY_MM_DD_HH.parseDateTime(dateStr).plusHours(1).getMillis();
case MINUTE:
return YYYY_MM_DD_HHMM.parseDateTime(dateStr).plusMinutes(1).getMillis();
case SECOND:
return YYYY_MM_DD_HHMMSS.parseDateTime(dateStr).plusSeconds(1).getMillis();
}
throw new UnexpectedException("Unsupported step " + step.name());
}
public int minutesBetween(Downsampling downsampling, DateTime dateTime) {
switch (downsampling) {
case Month:
return dateTime.dayOfMonth().getMaximumValue() * 24 * 60;
case Day:
return 24 * 60;
case Hour:
return 60;
default:
return 1;
}
}
public int secondsBetween(Downsampling downsampling, DateTime dateTime) {
switch (downsampling) {
case Month:
return dateTime.dayOfMonth().getMaximumValue() * 24 * 60 * 60;
case Day:
return 24 * 60 * 60;
case Hour:
return 60 * 60;
case Minute:
return 60;
default:
return 1;
}
}
public List<DurationPoint> getDurationPoints(Downsampling downsampling, long startTimeBucket,
long endTimeBucket) {
DateTime dateTime = parseToDateTime(downsampling, startTimeBucket);
List<DurationPoint> durations = new LinkedList<>();
durations.add(new DurationPoint(startTimeBucket, secondsBetween(downsampling, dateTime), minutesBetween(downsampling, dateTime)));
int i = 0;
do {
switch (downsampling) {
case Month:
dateTime = dateTime.plusMonths(1);
String timeBucket = YYYYMM.print(dateTime);
durations.add(new DurationPoint(Long.parseLong(timeBucket), secondsBetween(downsampling, dateTime), minutesBetween(downsampling, dateTime)));
break;
case Day:
dateTime = dateTime.plusDays(1);
timeBucket = YYYYMMDD.print(dateTime);
durations.add(new DurationPoint(Long.parseLong(timeBucket), secondsBetween(downsampling, dateTime), minutesBetween(downsampling, dateTime)));
break;
case Hour:
dateTime = dateTime.plusHours(1);
timeBucket = YYYYMMDDHH.print(dateTime);
durations.add(new DurationPoint(Long.parseLong(timeBucket), secondsBetween(downsampling, dateTime), minutesBetween(downsampling, dateTime)));
break;
case Minute:
dateTime = dateTime.plusMinutes(1);
timeBucket = YYYYMMDDHHMM.print(dateTime);
durations.add(new DurationPoint(Long.parseLong(timeBucket), secondsBetween(downsampling, dateTime), minutesBetween(downsampling, dateTime)));
break;
case Second:
dateTime = dateTime.plusSeconds(1);
timeBucket = YYYYMMDDHHMMSS.print(dateTime);
durations.add(new DurationPoint(Long.parseLong(timeBucket), secondsBetween(downsampling, dateTime), minutesBetween(downsampling, dateTime)));
break;
}
i++;
if (i > 500) {
throw new UnexpectedException("Duration data error, step: " + downsampling.name() + ", start: " + startTimeBucket + ", end: " + endTimeBucket);
}
}
while (endTimeBucket != durations.get(durations.size() - 1).getPoint());
return durations;
}
private DateTime parseToDateTime(Downsampling downsampling, long time) {
switch (downsampling) {
case Month:
return YYYYMM.parseDateTime(String.valueOf(time));
case Day:
return YYYYMMDD.parseDateTime(String.valueOf(time));
case Hour:
return YYYYMMDDHH.parseDateTime(String.valueOf(time));
case Minute:
return YYYYMMDDHHMM.parseDateTime(String.valueOf(time));
case Second:
return YYYYMMDDHHMMSS.parseDateTime(String.valueOf(time));
}
throw new UnexpectedException("Unexpected downsampling: " + downsampling.name());
}
}