fix(analytics): date ranges being queried in charts (#7444)

This commit is contained in:
Aseem Bansal 2023-02-27 21:42:40 +05:30 committed by GitHub
parent c12f3491a2
commit b203dd2895
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 120 additions and 34 deletions

View File

@ -18,6 +18,7 @@ import com.linkedin.datahub.graphql.generated.Row;
import com.linkedin.datahub.graphql.generated.TableChart;
import com.linkedin.datahub.graphql.generated.TimeSeriesChart;
import com.linkedin.datahub.graphql.resolvers.ResolverUtils;
import com.linkedin.datahub.graphql.util.DateUtil;
import com.linkedin.entity.client.EntityClient;
import com.linkedin.metadata.Constants;
import graphql.schema.DataFetcher;
@ -26,12 +27,10 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.function.Function;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.joda.time.DateTime;
import org.joda.time.DateTimeConstants;
/**
@ -64,14 +63,13 @@ public final class GetChartsResolver implements DataFetcher<List<AnalyticsChartG
}
private TimeSeriesChart getActiveUsersTimeSeriesChart(
final DateTime endDateTime,
final DateTime beginning,
final DateTime end,
final String title,
final DateInterval interval,
final Function<DateTime, DateTime> convertToBegin
final DateInterval interval
) {
final DateTime beginning = convertToBegin.apply(endDateTime);
final DateRange dateRange =
new DateRange(String.valueOf(beginning.getMillis()), String.valueOf(endDateTime.getMillis()));
new DateRange(String.valueOf(beginning.getMillis()), String.valueOf(end.getMillis()));
final List<NamedLine> timeSeriesLines =
_analyticsService.getTimeseriesChart(_analyticsService.getUsageIndexName(), dateRange, interval,
@ -89,33 +87,22 @@ public final class GetChartsResolver implements DataFetcher<List<AnalyticsChartG
*/
private List<AnalyticsChart> getProductAnalyticsCharts(Authentication authentication) throws Exception {
final List<AnalyticsChart> charts = new ArrayList<>();
final DateTime endOfWeek = DateTime.now()
.plusDays(1)
.withDayOfWeek(DateTimeConstants.SUNDAY)
.withHourOfDay(0)
.withMinuteOfHour(0)
.withSecondOfMinute(0)
.withMillisOfDay(0);
final DateTime startOfWeek = endOfWeek.minusWeeks(1);
final DateRange lastWeekDateRange =
new DateRange(String.valueOf(startOfWeek.getMillis()), String.valueOf(endOfWeek.getMillis()));
DateUtil dateUtil = new DateUtil();
final DateTime startOfNextWeek = dateUtil.getStartOfNextWeek();
final DateTime startOfNextMonth = dateUtil.getStartOfNextMonth();
final DateRange trailingWeekDateRange = dateUtil.getTrailingWeekDateRange();
charts.add(getActiveUsersTimeSeriesChart(
endOfWeek,
startOfNextWeek.minusWeeks(10),
startOfNextWeek.minusMillis(1),
"Weekly Active Users",
DateInterval.WEEK,
dateTime -> dateTime.minusMonths(2)
DateInterval.WEEK
));
charts.add(getActiveUsersTimeSeriesChart(
endOfWeek,
startOfNextMonth.minusMonths(12),
startOfNextMonth.minusMillis(1),
"Monthly Active Users",
DateInterval.MONTH,
dateTime -> dateTime.minusMonths(12)
.withDayOfMonth(1)
.withHourOfDay(0)
.withMinuteOfHour(0)
.withSecondOfMinute(0)
.withMillisOfDay(0)
DateInterval.MONTH
));
String searchesTitle = "Searches Last Week";
@ -123,12 +110,12 @@ public final class GetChartsResolver implements DataFetcher<List<AnalyticsChartG
String searchEventType = "SearchEvent";
final List<NamedLine> searchesTimeseries =
_analyticsService.getTimeseriesChart(_analyticsService.getUsageIndexName(), lastWeekDateRange, dailyInterval,
_analyticsService.getTimeseriesChart(_analyticsService.getUsageIndexName(), trailingWeekDateRange, dailyInterval,
Optional.empty(), ImmutableMap.of("type", ImmutableList.of(searchEventType)), Collections.emptyMap(),
Optional.empty());
charts.add(TimeSeriesChart.builder()
.setTitle(searchesTitle)
.setDateRange(lastWeekDateRange)
.setDateRange(trailingWeekDateRange)
.setInterval(dailyInterval)
.setLines(searchesTimeseries)
.build());
@ -137,14 +124,14 @@ public final class GetChartsResolver implements DataFetcher<List<AnalyticsChartG
final List<String> columns = ImmutableList.of("Query", "Count");
final List<Row> topSearchQueries =
_analyticsService.getTopNTableChart(_analyticsService.getUsageIndexName(), Optional.of(lastWeekDateRange),
_analyticsService.getTopNTableChart(_analyticsService.getUsageIndexName(), Optional.of(trailingWeekDateRange),
"query.keyword", ImmutableMap.of("type", ImmutableList.of(searchEventType)), Collections.emptyMap(),
Optional.empty(), 10, AnalyticsUtil::buildCellWithSearchLandingPage);
charts.add(TableChart.builder().setTitle(topSearchTitle).setColumns(columns).setRows(topSearchQueries).build());
final String sectionViewsTitle = "Section Views across Entity Types";
final List<NamedBar> sectionViewsPerEntityType =
_analyticsService.getBarChart(_analyticsService.getUsageIndexName(), Optional.of(lastWeekDateRange),
_analyticsService.getBarChart(_analyticsService.getUsageIndexName(), Optional.of(trailingWeekDateRange),
ImmutableList.of("entityType.keyword", "section.keyword"),
ImmutableMap.of("type", ImmutableList.of("EntitySectionViewEvent")), Collections.emptyMap(),
Optional.empty(), true);
@ -152,7 +139,7 @@ public final class GetChartsResolver implements DataFetcher<List<AnalyticsChartG
final String actionsByTypeTitle = "Actions by Entity Type";
final List<NamedBar> eventsByEventType =
_analyticsService.getBarChart(_analyticsService.getUsageIndexName(), Optional.of(lastWeekDateRange),
_analyticsService.getBarChart(_analyticsService.getUsageIndexName(), Optional.of(trailingWeekDateRange),
ImmutableList.of("entityType.keyword", "actionType.keyword"),
ImmutableMap.of("type", ImmutableList.of("EntityActionEvent")), Collections.emptyMap(), Optional.empty(),
true);
@ -162,7 +149,7 @@ public final class GetChartsResolver implements DataFetcher<List<AnalyticsChartG
final List<String> columns5 = ImmutableList.of("Dataset", "#Views");
final List<Row> topViewedDatasets =
_analyticsService.getTopNTableChart(_analyticsService.getUsageIndexName(), Optional.of(lastWeekDateRange),
_analyticsService.getTopNTableChart(_analyticsService.getUsageIndexName(), Optional.of(trailingWeekDateRange),
"entityUrn.keyword", ImmutableMap.of("type", ImmutableList.of("EntityViewEvent"), "entityType.keyword",
ImmutableList.of(EntityType.DATASET.name())), Collections.emptyMap(), Optional.empty(), 10,
AnalyticsUtil::buildCellWithEntityLandingPage);

View File

@ -0,0 +1,43 @@
package com.linkedin.datahub.graphql.util;
import com.linkedin.datahub.graphql.generated.DateRange;
import org.joda.time.DateTime;
import org.joda.time.DateTimeConstants;
public class DateUtil {
public DateTime getNow() {
return DateTime.now();
}
public DateTime getStartOfNextWeek() {
return setTimeToZero(getNow()
.withDayOfWeek(DateTimeConstants.SUNDAY)
.plusDays(1));
}
public DateTime getStartOfNextMonth() {
return setTimeToZero(getNow()
.withDayOfMonth(1)
.plusMonths(1));
}
public DateTime setTimeToZero(DateTime input) {
return input.withHourOfDay(0)
.withMinuteOfHour(0)
.withSecondOfMinute(0)
.withMillisOfDay(0);
}
public DateTime getTomorrowStart() {
return setTimeToZero(getNow().plusDays(1));
}
public DateRange getTrailingWeekDateRange() {
final DateTime todayEnd = getTomorrowStart().minusMillis(1);
final DateTime aWeekAgoStart = todayEnd.minusWeeks(1).plusMillis(1);
return new DateRange(
String.valueOf(aWeekAgoStart.getMillis()),
String.valueOf(todayEnd.getMillis())
);
}
}

View File

@ -0,0 +1,56 @@
package com.linkedin.datahub.graphql.utils;
import com.linkedin.datahub.graphql.util.DateUtil;
import junit.framework.TestCase;
import org.joda.time.DateTime;
import org.mockito.Mockito;
import org.testng.annotations.Test;
public class DateUtilTest extends TestCase {
private DateTime setTimeParts(int dayOfMonth, boolean zeroTime) {
DateTime result = new DateTime()
.withDate(2023, 1, dayOfMonth);
if (zeroTime) {
return new DateUtil().setTimeToZero(result);
}
return result
.withHourOfDay(1)
.withMinuteOfHour(2)
.withSecondOfMinute(3)
.withMillisOfSecond(4);
}
private void assertEqualStartOfNextWeek(DateUtil dateUtil, int dayOfMonth) {
assertEquals(
setTimeParts(dayOfMonth, true).getMillis(),
dateUtil.getStartOfNextWeek().getMillis()
);
}
@Test
public void testStartOfNextWeek() {
DateUtil dateUtil = Mockito.spy(DateUtil.class);
Mockito.when(dateUtil.getNow()).thenReturn(setTimeParts(2, false));
assertEqualStartOfNextWeek(dateUtil, 9);
Mockito.when(dateUtil.getNow()).thenReturn(setTimeParts(3, false));
assertEqualStartOfNextWeek(dateUtil, 9);
Mockito.when(dateUtil.getNow()).thenReturn(setTimeParts(4, false));
assertEqualStartOfNextWeek(dateUtil, 9);
Mockito.when(dateUtil.getNow()).thenReturn(setTimeParts(5, false));
assertEqualStartOfNextWeek(dateUtil, 9);
Mockito.when(dateUtil.getNow()).thenReturn(setTimeParts(6, false));
assertEqualStartOfNextWeek(dateUtil, 9);
Mockito.when(dateUtil.getNow()).thenReturn(setTimeParts(7, false));
assertEqualStartOfNextWeek(dateUtil, 9);
Mockito.when(dateUtil.getNow()).thenReturn(setTimeParts(8, false));
assertEqualStartOfNextWeek(dateUtil, 9);
}
}