Merge pull request #5401 from umbraco/v8/feature/logviewer-change-time-period

Added support for changing the dates of the log files
This commit is contained in:
Warren Buckley
2019-06-18 15:09:16 +01:00
committed by GitHub
14 changed files with 275 additions and 144 deletions

View File

@@ -26,26 +26,26 @@ namespace Umbraco.Core.Logging.Viewer
/// A count of number of errors
/// By counting Warnings with Exceptions, Errors & Fatal messages
/// </summary>
int GetNumberOfErrors(DateTimeOffset startDate, DateTimeOffset endDate);
int GetNumberOfErrors(LogTimePeriod logTimePeriod);
/// <summary>
/// Returns a number of the different log level entries
/// </summary>
LogLevelCounts GetLogLevelCounts(DateTimeOffset startDate, DateTimeOffset endDate);
LogLevelCounts GetLogLevelCounts(LogTimePeriod logTimePeriod);
/// <summary>
/// Returns a list of all unique message templates and their counts
/// </summary>
IEnumerable<LogTemplate> GetMessageTemplates(DateTimeOffset startDate, DateTimeOffset endDate);
IEnumerable<LogTemplate> GetMessageTemplates(LogTimePeriod logTimePeriod);
bool CanHandleLargeLogs { get; }
bool CheckCanOpenLogs(DateTimeOffset startDate, DateTimeOffset endDate);
bool CheckCanOpenLogs(LogTimePeriod logTimePeriod);
/// <summary>
/// Returns the collection of logs
/// </summary>
PagedResult<LogMessage> GetLogs(DateTimeOffset startDate, DateTimeOffset endDate,
PagedResult<LogMessage> GetLogs(LogTimePeriod logTimePeriod,
int pageNumber = 1,
int pageSize = 100,
Direction orderDirection = Direction.Descending,

View File

@@ -26,7 +26,7 @@ namespace Umbraco.Core.Logging.Viewer
public override bool CanHandleLargeLogs => false;
public override bool CheckCanOpenLogs(DateTimeOffset startDate, DateTimeOffset endDate)
public override bool CheckCanOpenLogs(LogTimePeriod logTimePeriod)
{
//Log Directory
var logDirectory = _logsPath;
@@ -36,7 +36,7 @@ namespace Umbraco.Core.Logging.Viewer
//foreach full day in the range - see if we can find one or more filenames that end with
//yyyyMMdd.json - Ends with due to MachineName in filenames - could be 1 or more due to load balancing
for (var day = startDate.Date; day.Date <= endDate.Date; day = day.AddDays(1))
for (var day = logTimePeriod.StartTime.Date; day.Date <= logTimePeriod.EndTime.Date; day = day.AddDays(1))
{
//Filename ending to search for (As could be multiple)
var filesToFind = GetSearchPattern(day);
@@ -57,7 +57,7 @@ namespace Umbraco.Core.Logging.Viewer
return $"*{day:yyyyMMdd}*.json";
}
protected override IReadOnlyList<LogEvent> GetLogs(DateTimeOffset startDate, DateTimeOffset endDate, ILogFilter filter, int skip, int take)
protected override IReadOnlyList<LogEvent> GetLogs(LogTimePeriod logTimePeriod, ILogFilter filter, int skip, int take)
{
var logs = new List<LogEvent>();
@@ -68,7 +68,7 @@ namespace Umbraco.Core.Logging.Viewer
//foreach full day in the range - see if we can find one or more filenames that end with
//yyyyMMdd.json - Ends with due to MachineName in filenames - could be 1 or more due to load balancing
for (var day = startDate.Date; day.Date <= endDate.Date; day = day.AddDays(1))
for (var day = logTimePeriod.StartTime.Date; day.Date <= logTimePeriod.EndTime.Date; day = day.AddDays(1))
{
//Filename ending to search for (As could be multiple)
var filesToFind = GetSearchPattern(day);

View File

@@ -0,0 +1,16 @@
using System;
namespace Umbraco.Core.Logging.Viewer
{
public class LogTimePeriod
{
public LogTimePeriod(DateTime startTime, DateTime endTime)
{
StartTime = startTime;
EndTime = endTime;
}
public DateTime StartTime { get; }
public DateTime EndTime { get; }
}
}

View File

@@ -27,9 +27,9 @@ namespace Umbraco.Core.Logging.Viewer
/// <summary>
/// Get all logs from your chosen data source back as Serilog LogEvents
/// </summary>
protected abstract IReadOnlyList<LogEvent> GetLogs(DateTimeOffset startDate, DateTimeOffset endDate, ILogFilter filter, int skip, int take);
protected abstract IReadOnlyList<LogEvent> GetLogs(LogTimePeriod logTimePeriod, ILogFilter filter, int skip, int take);
public abstract bool CheckCanOpenLogs(DateTimeOffset startDate, DateTimeOffset endDate);
public abstract bool CheckCanOpenLogs(LogTimePeriod logTimePeriod);
public virtual IReadOnlyList<SavedLogSearch> GetSavedSearches()
{
@@ -82,24 +82,24 @@ namespace Umbraco.Core.Logging.Viewer
return searches;
}
public int GetNumberOfErrors(DateTimeOffset startDate, DateTimeOffset endDate)
public int GetNumberOfErrors(LogTimePeriod logTimePeriod)
{
var errorCounter = new ErrorCounterFilter();
GetLogs(startDate, endDate, errorCounter, 0, int.MaxValue);
GetLogs(logTimePeriod, errorCounter, 0, int.MaxValue);
return errorCounter.Count;
}
public LogLevelCounts GetLogLevelCounts(DateTimeOffset startDate, DateTimeOffset endDate)
public LogLevelCounts GetLogLevelCounts(LogTimePeriod logTimePeriod)
{
var counter = new CountingFilter();
GetLogs(startDate, endDate, counter, 0, int.MaxValue);
GetLogs(logTimePeriod, counter, 0, int.MaxValue);
return counter.Counts;
}
public IEnumerable<LogTemplate> GetMessageTemplates(DateTimeOffset startDate, DateTimeOffset endDate)
public IEnumerable<LogTemplate> GetMessageTemplates(LogTimePeriod logTimePeriod)
{
var messageTemplates = new MessageTemplateFilter();
GetLogs(startDate, endDate, messageTemplates, 0, int.MaxValue);
GetLogs(logTimePeriod, messageTemplates, 0, int.MaxValue);
var templates = messageTemplates.Counts.
Select(x => new LogTemplate { MessageTemplate = x.Key, Count = x.Value })
@@ -108,14 +108,14 @@ namespace Umbraco.Core.Logging.Viewer
return templates;
}
public PagedResult<LogMessage> GetLogs(DateTimeOffset startDate, DateTimeOffset endDate,
public PagedResult<LogMessage> GetLogs(LogTimePeriod logTimePeriod,
int pageNumber = 1, int pageSize = 100,
Direction orderDirection = Direction.Descending,
string filterExpression = null,
string[] logLevels = null)
{
var expression = new ExpressionFilter(filterExpression);
var filteredLogs = GetLogs(startDate, endDate, expression, 0, int.MaxValue);
var filteredLogs = GetLogs(logTimePeriod, expression, 0, int.MaxValue);
//This is user used the checkbox UI to toggle which log levels they wish to see
//If an empty array or null - its implied all levels to be viewed

View File

@@ -218,6 +218,7 @@
<Compile Include="Composing\TypeHelper.cs" />
<Compile Include="Composing\TypeLoader.cs" />
<Compile Include="IO\MediaPathSchemes\UniqueMediaPathScheme.cs" />
<Compile Include="Logging\Viewer\LogTimePeriod.cs" />
<Compile Include="Mapping\MapperContext.cs" />
<Compile Include="Migrations\Upgrade\Common\DeleteKeysAndIndexes.cs" />
<Compile Include="Migrations\Upgrade\V_8_0_0\DataTypes\ContentPickerPreValueMigrator.cs" />

View File

@@ -23,9 +23,10 @@ namespace Umbraco.Tests.Logging
private string _newSearchfilePath;
private string _newSearchfileDirPath;
private DateTimeOffset _startDate = new DateTime(year: 2018, month: 11, day: 12, hour:0, minute:0, second:0);
private DateTimeOffset _endDate = new DateTime(year: 2018, month: 11, day: 13, hour: 0, minute: 0, second: 0);
private LogTimePeriod _logTimePeriod = new LogTimePeriod(
new DateTime(year: 2018, month: 11, day: 12, hour:0, minute:0, second:0),
new DateTime(year: 2018, month: 11, day: 13, hour: 0, minute: 0, second: 0)
);
[OneTimeSetUp]
public void Setup()
{
@@ -67,7 +68,7 @@ namespace Umbraco.Tests.Logging
[Test]
public void Logs_Contain_Correct_Error_Count()
{
var numberOfErrors = _logViewer.GetNumberOfErrors(startDate: _startDate, endDate: _endDate);
var numberOfErrors = _logViewer.GetNumberOfErrors(_logTimePeriod);
//Our dummy log should contain 2 errors
Assert.AreEqual(2, numberOfErrors);
@@ -76,8 +77,8 @@ namespace Umbraco.Tests.Logging
[Test]
public void Logs_Contain_Correct_Log_Level_Counts()
{
var logCounts = _logViewer.GetLogLevelCounts(startDate: _startDate, endDate: _endDate);
var logCounts = _logViewer.GetLogLevelCounts(_logTimePeriod);
Assert.AreEqual(1954, logCounts.Debug);
Assert.AreEqual(2, logCounts.Error);
Assert.AreEqual(0, logCounts.Fatal);
@@ -88,7 +89,7 @@ namespace Umbraco.Tests.Logging
[Test]
public void Logs_Contains_Correct_Message_Templates()
{
var templates = _logViewer.GetMessageTemplates(startDate: _startDate, endDate: _endDate);
var templates = _logViewer.GetMessageTemplates(_logTimePeriod);
//Count no of templates
Assert.AreEqual(43, templates.Count());
@@ -112,7 +113,7 @@ namespace Umbraco.Tests.Logging
{
//We are just testing a return value (as we know the example file is less than 200MB)
//But this test method does not test/check that
var canOpenLogs = _logViewer.CheckCanOpenLogs(startDate: _startDate, endDate: _endDate);
var canOpenLogs = _logViewer.CheckCanOpenLogs(_logTimePeriod);
Assert.IsTrue(canOpenLogs);
}
@@ -120,7 +121,7 @@ namespace Umbraco.Tests.Logging
public void Logs_Can_Be_Queried()
{
//Should get me the most 100 recent log entries & using default overloads for remaining params
var allLogs = _logViewer.GetLogs(startDate: _startDate, endDate: _endDate, pageNumber: 1);
var allLogs = _logViewer.GetLogs(_logTimePeriod, pageNumber: 1);
//Check we get 100 results back for a page & total items all good :)
Assert.AreEqual(100, allLogs.Items.Count());
@@ -138,7 +139,7 @@ namespace Umbraco.Tests.Logging
//Check we call method again with a smaller set of results & in ascending
var smallQuery = _logViewer.GetLogs(startDate: _startDate, endDate: _endDate, pageNumber: 1, pageSize: 10, orderDirection: Direction.Ascending);
var smallQuery = _logViewer.GetLogs(_logTimePeriod, pageNumber: 1, pageSize: 10, orderDirection: Direction.Ascending);
Assert.AreEqual(10, smallQuery.Items.Count());
Assert.AreEqual(241, smallQuery.TotalPages);
@@ -152,17 +153,17 @@ namespace Umbraco.Tests.Logging
//Check invalid log levels
//Rather than expect 0 items - get all items back & ignore the invalid levels
string[] invalidLogLevels = { "Invalid", "NotALevel" };
var queryWithInvalidLevels = _logViewer.GetLogs(startDate: _startDate, endDate: _endDate, pageNumber: 1, logLevels: invalidLogLevels);
var queryWithInvalidLevels = _logViewer.GetLogs(_logTimePeriod, pageNumber: 1, logLevels: invalidLogLevels);
Assert.AreEqual(2410, queryWithInvalidLevels.TotalItems);
//Check we can call method with an array of logLevel (error & warning)
string [] logLevels = { "Warning", "Error" };
var queryWithLevels = _logViewer.GetLogs(startDate: _startDate, endDate: _endDate, pageNumber: 1, logLevels: logLevels);
var queryWithLevels = _logViewer.GetLogs(_logTimePeriod, pageNumber: 1, logLevels: logLevels);
Assert.AreEqual(9, queryWithLevels.TotalItems);
//Query @Level='Warning' BUT we pass in array of LogLevels for Debug & Info (Expect to get 0 results)
string[] logLevelMismatch = { "Debug", "Information" };
var filterLevelQuery = _logViewer.GetLogs(startDate: _startDate, endDate: _endDate, pageNumber: 1, filterExpression: "@Level='Warning'", logLevels: logLevelMismatch); ;
var filterLevelQuery = _logViewer.GetLogs(_logTimePeriod, pageNumber: 1, filterExpression: "@Level='Warning'", logLevels: logLevelMismatch); ;
Assert.AreEqual(0, filterLevelQuery.TotalItems);
}
@@ -177,10 +178,10 @@ namespace Umbraco.Tests.Logging
[Test]
public void Logs_Can_Query_With_Expressions(string queryToVerify, int expectedCount)
{
var testQuery = _logViewer.GetLogs(startDate: _startDate, endDate: _endDate, pageNumber: 1, filterExpression: queryToVerify);
var testQuery = _logViewer.GetLogs(_logTimePeriod, pageNumber: 1, filterExpression: queryToVerify);
Assert.AreEqual(expectedCount, testQuery.TotalItems);
}
[Test]
public void Log_Search_Can_Persist()
{

View File

@@ -96,13 +96,13 @@ Use this directive to generate a pagination.
scope.pageNumber = parseInt(scope.pageNumber);
}
scope.pagination = [];
let tempPagination = [];
var i = 0;
if (scope.totalPages <= 10) {
for (i = 0; i < scope.totalPages; i++) {
scope.pagination.push({
tempPagination.push({
val: (i + 1),
isActive: scope.pageNumber === (i + 1)
});
@@ -119,7 +119,7 @@ Use this directive to generate a pagination.
start = Math.min(maxIndex, start);
for (i = start; i < (10 + start) ; i++) {
scope.pagination.push({
tempPagination.push({
val: (i + 1),
isActive: scope.pageNumber === (i + 1)
});
@@ -129,7 +129,7 @@ Use this directive to generate a pagination.
if (start > 0) {
localizationService.localize("general_first").then(function(value){
var firstLabel = value;
scope.pagination.unshift({ name: firstLabel, val: 1, isActive: false }, {val: "...",isActive: false});
tempPagination.unshift({ name: firstLabel, val: 1, isActive: false }, {val: "...",isActive: false});
});
}
@@ -137,9 +137,11 @@ Use this directive to generate a pagination.
if (start < maxIndex) {
localizationService.localize("general_last").then(function(value){
var lastLabel = value;
scope.pagination.push({ val: "...", isActive: false }, { name: lastLabel, val: scope.totalPages, isActive: false });
tempPagination.push({ val: "...", isActive: false }, { name: lastLabel, val: scope.totalPages, isActive: false });
});
}
scope.pagination = tempPagination;
}
}

View File

@@ -1,39 +1,39 @@
/**
* @ngdoc service
* @name umbraco.resources.logViewerResource
* @description Retrives Umbraco log items (by default from JSON files on disk)
*
*
**/
function logViewerResource($q, $http, umbRequestHelper) {
* @ngdoc service
* @name umbraco.resources.logViewerResource
* @description Retrives Umbraco log items (by default from JSON files on disk)
*
*
**/
function logViewerResource($q, $http, umbRequestHelper) {
//the factory object returned
return {
getNumberOfErrors: function () {
getNumberOfErrors: function (startDate, endDate) {
return umbRequestHelper.resourcePromise(
$http.get(
umbRequestHelper.getApiUrl(
"logViewerApiBaseUrl",
"GetNumberOfErrors")),
"GetNumberOfErrors")+ '?startDate='+startDate+ '&endDate='+ endDate ),
'Failed to retrieve number of errors in logs');
},
getLogLevelCounts: function () {
getLogLevelCounts: function (startDate, endDate) {
return umbRequestHelper.resourcePromise(
$http.get(
umbRequestHelper.getApiUrl(
"logViewerApiBaseUrl",
"GetLogLevelCounts")),
"GetLogLevelCounts")+ '?startDate='+startDate+ '&endDate='+ endDate ),
'Failed to retrieve log level counts');
},
getMessageTemplates: function () {
getMessageTemplates: function (startDate, endDate) {
return umbRequestHelper.resourcePromise(
$http.get(
umbRequestHelper.getApiUrl(
"logViewerApiBaseUrl",
"GetMessageTemplates")),
"GetMessageTemplates")+ '?startDate='+startDate+ '&endDate='+ endDate ),
'Failed to retrieve log templates');
},
@@ -93,12 +93,12 @@
'Failed to retrieve common log messages');
},
canViewLogs: function () {
canViewLogs: function (startDate, endDate) {
return umbRequestHelper.resourcePromise(
$http.get(
umbRequestHelper.getApiUrl(
"logViewerApiBaseUrl",
"GetCanViewLogs")),
"GetCanViewLogs") + '?startDate='+startDate+ '&endDate='+ endDate ),
'Failed to retrieve state if logs can be viewed');
}

View File

@@ -20,6 +20,15 @@
.umb-logviewer__sidebar {
flex: 0 0 @sidebarwidth;
.flatpickr-input {
background-color: @white;
border: 0;
width: 100%;
text-align: center;
font-size: larger;
padding-top: 20px;
}
}
@media (max-width: 768px) {

View File

@@ -22,16 +22,32 @@
}
};
let querystring = $location.search();
if(querystring.startDate){
vm.startDate = querystring.startDate;
}else{
vm.startDate = new Date(Date.now());
vm.startDate.setDate(vm.startDate.getDate()-1);
vm.startDate = vm.startDate.toIsoDateString();
}
if(querystring.endDate){
vm.endDate = querystring.endDate;
}else{
vm.endDate = new Date(Date.now()).toIsoDateString();
}
vm.period = [vm.startDate, vm.endDate];
//functions
vm.searchLogQuery = searchLogQuery;
vm.findMessageTemplate = findMessageTemplate;
function preFlightCheck(){
vm.loading = true;
//Do our pre-flight check (to see if we can view logs)
//IE the log file is NOT too big such as 1GB & crash the site
logViewerResource.canViewLogs().then(function(result){
logViewerResource.canViewLogs(vm.startDate, vm.endDate).then(function(result){
vm.loading = false;
vm.canLoadLogs = result;
@@ -46,7 +62,7 @@
function init() {
vm.loading = true;
var savedSearches = logViewerResource.getSavedSearches().then(function (data) {
vm.searches = data;
},
@@ -80,11 +96,11 @@
]
});
var numOfErrors = logViewerResource.getNumberOfErrors().then(function (data) {
var numOfErrors = logViewerResource.getNumberOfErrors(vm.startDate, vm.endDate).then(function (data) {
vm.numberOfErrors = data;
});
var logCounts = logViewerResource.getLogLevelCounts().then(function (data) {
var logCounts = logViewerResource.getLogLevelCounts(vm.startDate, vm.endDate).then(function (data) {
vm.logTypeData = [];
vm.logTypeData.push(data.Information);
vm.logTypeData.push(data.Debug);
@@ -93,7 +109,7 @@
vm.logTypeData.push(data.Fatal);
});
var commonMsgs = logViewerResource.getMessageTemplates().then(function(data){
var commonMsgs = logViewerResource.getMessageTemplates(vm.startDate, vm.endDate).then(function(data){
vm.commonLogMessages = data;
});
@@ -108,7 +124,7 @@
}
function searchLogQuery(logQuery){
$location.path("/settings/logViewer/search").search({lq: logQuery});
$location.path("/settings/logViewer/search").search({lq: logQuery, startDate: vm.startDate, endDate: vm.endDate});
}
function findMessageTemplate(template){
@@ -116,8 +132,38 @@
searchLogQuery(logQuery);
}
preFlightCheck();
preFlightCheck();
/////////////////////
vm.config = {
enableTime: false,
dateFormat: "Y-m-d",
time_24hr: false,
mode: "range",
maxDate: "today",
conjunction: " to "
};
vm.dateRangeChange = function(selectedDates, dateStr, instance) {
if(selectedDates.length > 0){
vm.startDate = selectedDates[0].toIsoDateString();
vm.endDate = selectedDates[selectedDates.length-1].toIsoDateString(); // Take the last date as end
if(vm.startDate === vm.endDate){
vm.period = [vm.startDate];
}else{
vm.period = [vm.startDate, vm.endDate];
}
preFlightCheck();
}
}
}
angular.module("umbraco").controller("Umbraco.Editors.LogViewer.OverviewController", LogViewerOverviewController);

View File

@@ -14,45 +14,45 @@
<umb-load-indicator ng-if="vm.loading"></umb-load-indicator>
<!-- Warning message (if unable to view log files) -->
<div ng-show="!vm.loading && !vm.canLoadLogs">
<umb-box>
<umb-box-header title="Unable to view logs"/>
<umb-box-content>
<p>Today's log file is too large to be viewed and would cause performance problems.</p>
<p>If you need to view the log files, try opening them manually</p>
</umb-box-content>
</umb-box>
</div>
<div class="umb-logviewer" ng-show="!vm.loading && vm.canLoadLogs">
<div class="umb-logviewer" ng-show="!vm.loading">
<div class="umb-logviewer__main-content">
<!-- Saved Searches -->
<umb-box>
<umb-box-header title="Saved Searches"></umb-box-header>
<umb-box-content>
<table>
<tr>
<td>
<a ng-click="vm.searchLogQuery()" title="View all Logs" class="btn btn-link">All Logs <i class="icon-search"></i></a>
</td>
</tr>
<!-- Fetch saved searches -->
<tr ng-repeat="search in vm.searches">
<td>
<a ng-click="vm.searchLogQuery(search.query)" title="{{search.name}}" class="btn btn-link">{{search.name}} <i class="icon-search"></i></a>
</td>
</tr>
</table>
</umb-box-content>
</umb-box>
<div ng-show="!vm.canLoadLogs">
<umb-box>
<umb-box-header title="Unable to view logs"/>
<umb-box-content>
<p>Today's log file is too large to be viewed and would cause performance problems.</p>
<p>If you need to view the log files, try opening them manually</p>
</umb-box-content>
</umb-box>
</div>
<div ng-show="vm.canLoadLogs">
<!-- Saved Searches -->
<umb-box>
<umb-box-header title="Saved Searches"></umb-box-header>
<umb-box-content>
<table>
<tr>
<td>
<a ng-click="vm.searchLogQuery()" title="View all Logs" class="btn btn-link">All Logs <i class="icon-search"></i></a>
</td>
</tr>
<!-- Fetch saved searches -->
<tr ng-repeat="search in vm.searches">
<td>
<a ng-click="vm.searchLogQuery(search.query)" title="{{search.name}}" class="btn btn-link">{{search.name}} <i class="icon-search"></i></a>
</td>
</tr>
</table>
</umb-box-content>
</umb-box>
<!-- List of top X common log messages -->
<umb-box>
<umb-box-header title="Common Log Messages"></umb-box-header>
<umb-box-content class="block-form">
<em>Total Unique Message types</em>: {{ vm.commonLogMessages.length }}
<table class="table table-hover">
<tbody>
<!-- List of top X common log messages -->
<umb-box>
<umb-box-header title="Common Log Messages"></umb-box-header>
<umb-box-content class="block-form">
<em>Total Unique Message types</em>: {{ vm.commonLogMessages.length }}
<table class="table table-hover">
<tbody>
<tr ng-repeat="template in vm.commonLogMessages | limitTo:vm.commonLogMessagesCount" ng-click="vm.findMessageTemplate(template)" style="cursor: pointer;">
<td>
{{ template.MessageTemplate }}
@@ -61,38 +61,54 @@
{{ template.Count }}
</td>
</tr>
</tbody>
</table>
<a class="btn btn-primary" ng-if="vm.commonLogMessagesCount < vm.commonLogMessages.length" ng-click="vm.commonLogMessagesCount = vm.commonLogMessagesCount +10">Show More</a>
</umb-box-content>
</umb-box>
</tbody>
</table>
<a class="btn btn-primary" ng-if="vm.commonLogMessagesCount < vm.commonLogMessages.length" ng-click="vm.commonLogMessagesCount = vm.commonLogMessagesCount +10">Show More</a>
</umb-box-content>
</umb-box>
</div>
</div>
<div class="umb-logviewer__sidebar">
<!-- No of Errors -->
<umb-box ng-click="vm.searchLogQuery('Has(@Exception)')" style="cursor:pointer;">
<umb-box-header title="Number of Errors"></umb-box-header>
<umb-box-content class="block-form" style="font-size: 40px; font-weight:900; text-align:center; color:#fe6561;">
{{ vm.numberOfErrors }}
</umb-box-content>
</umb-box>
<!-- Chart of diff log types -->
<!-- Time period -->
<umb-box>
<umb-box-header title="Log Types"></umb-box-header>
<umb-box-content class="block-form">
<umb-box-header title="Time Period"></umb-box-header>
<canvas chart-doughnut
chart-data="vm.logTypeData"
chart-labels="vm.logTypeLabels"
chart-colors="vm.logTypeColors"
chart-options="vm.chartOptions">
</canvas>
</umb-box-content>
<umb-flatpickr
class="datepicker"
ng-model="vm.period"
options="vm.config"
on-close="vm.dateRangeChange(selectedDates, dateStr, instance)">
</umb-flatpickr>
</umb-box>
<div ng-show=" vm.canLoadLogs">
<!-- No of Errors -->
<umb-box ng-click="vm.searchLogQuery('Has(@Exception)')" style="cursor:pointer;">
<umb-box-header title="Number of Errors"></umb-box-header>
<umb-box-content class="block-form" style="font-size: 40px; font-weight:900; text-align:center; color:#fe6561;">
{{ vm.numberOfErrors }}
</umb-box-content>
</umb-box>
<!-- Chart of diff log types -->
<umb-box>
<umb-box-header title="Log Types"></umb-box-header>
<umb-box-content class="block-form">
<canvas chart-doughnut
chart-data="vm.logTypeData"
chart-labels="vm.logTypeLabels"
chart-colors="vm.logTypeColors"
chart-options="vm.chartOptions">
</canvas>
</umb-box-content>
</umb-box>
</div>
</div>
</div>
</umb-editor-container>
</umb-editor-view>
</div>

View File

@@ -96,6 +96,14 @@
vm.logOptions.filterExpression = querystring.lq;
}
if(querystring.startDate){
vm.logOptions.startDate = querystring.startDate;
}
if(querystring.endDate){
vm.logOptions.endDate = querystring.endDate;
}
vm.loading = true;
logViewerResource.getSavedSearches().then(function (data) {
@@ -270,7 +278,11 @@
submitButtonLabel: "Save Search",
disableSubmitButton: true,
view: "logviewersearch",
query: vm.logOptions.filterExpression,
query: {
filterExpression: vm.logOptions.filterExpression,
startDate: vm.logOptions.startDate,
endDate: vm.logOptions.endDate
},
submit: function (model) {
//Resource call with two params (name & query)
//API that opens the JSON and adds it to the bottom

View File

@@ -184,7 +184,7 @@ namespace Umbraco.Web.Editors
{
"currentUserApiBaseUrl", _urlHelper.GetUmbracoApiServiceBaseUrl<CurrentUserController>(
controller => controller.PostChangePassword(null))
},
},
{
"entityApiBaseUrl", _urlHelper.GetUmbracoApiServiceBaseUrl<EntityController>(
controller => controller.GetById(0, UmbracoEntityTypes.Media))
@@ -307,7 +307,7 @@ namespace Umbraco.Web.Editors
},
{
"logViewerApiBaseUrl", _urlHelper.GetUmbracoApiServiceBaseUrl<LogViewerController>(
controller => controller.GetNumberOfErrors())
controller => controller.GetNumberOfErrors(null, null))
}
}
},

View File

@@ -22,69 +22,97 @@ namespace Umbraco.Web.Editors
_logViewer = logViewer;
}
private bool CanViewLogs()
private bool CanViewLogs(LogTimePeriod logTimePeriod)
{
//Can the interface deal with Large Files
if (_logViewer.CanHandleLargeLogs)
return true;
//Interface CheckCanOpenLogs
return _logViewer.CheckCanOpenLogs(startDate: DateTime.Now.AddDays(-1), endDate: DateTime.Now);
return _logViewer.CheckCanOpenLogs(logTimePeriod);
}
[HttpGet]
public bool GetCanViewLogs()
public bool GetCanViewLogs([FromUri] DateTime? startDate = null,[FromUri] DateTime? endDate = null)
{
return CanViewLogs();
var logTimePeriod = GetTimePeriod(startDate, endDate);
return CanViewLogs(logTimePeriod);
}
[HttpGet]
public int GetNumberOfErrors()
public int GetNumberOfErrors([FromUri] DateTime? startDate = null,[FromUri] DateTime? endDate = null)
{
var logTimePeriod = GetTimePeriod(startDate, endDate);
//We will need to stop the request if trying to do this on a 1GB file
if (CanViewLogs() == false)
if (CanViewLogs(logTimePeriod) == false)
{
throw new HttpResponseException(Request.CreateNotificationValidationErrorResponse("Unable to view logs, due to size"));
}
return _logViewer.GetNumberOfErrors(startDate: DateTime.Now.AddDays(-1), endDate: DateTime.Now);
return _logViewer.GetNumberOfErrors(logTimePeriod);
}
[HttpGet]
public LogLevelCounts GetLogLevelCounts()
public LogLevelCounts GetLogLevelCounts([FromUri] DateTime? startDate = null,[FromUri] DateTime? endDate = null)
{
var logTimePeriod = GetTimePeriod(startDate, endDate);
//We will need to stop the request if trying to do this on a 1GB file
if (CanViewLogs() == false)
if (CanViewLogs(logTimePeriod) == false)
{
throw new HttpResponseException(Request.CreateNotificationValidationErrorResponse("Unable to view logs, due to size"));
}
return _logViewer.GetLogLevelCounts(startDate: DateTime.Now.AddDays(-1), endDate: DateTime.Now);
return _logViewer.GetLogLevelCounts(logTimePeriod);
}
[HttpGet]
public IEnumerable<LogTemplate> GetMessageTemplates()
public IEnumerable<LogTemplate> GetMessageTemplates([FromUri] DateTime? startDate = null,[FromUri] DateTime? endDate = null)
{
var logTimePeriod = GetTimePeriod(startDate, endDate);
//We will need to stop the request if trying to do this on a 1GB file
if (CanViewLogs() == false)
if (CanViewLogs(logTimePeriod) == false)
{
throw new HttpResponseException(Request.CreateNotificationValidationErrorResponse("Unable to view logs, due to size"));
}
return _logViewer.GetMessageTemplates(startDate: DateTime.Now.AddDays(-1), endDate: DateTime.Now);
return _logViewer.GetMessageTemplates(logTimePeriod);
}
[HttpGet]
public PagedResult<LogMessage> GetLogs(string orderDirection = "Descending", int pageNumber = 1, string filterExpression = null, [FromUri]string[] logLevels = null)
public PagedResult<LogMessage> GetLogs(string orderDirection = "Descending", int pageNumber = 1, string filterExpression = null, [FromUri]string[] logLevels = null, [FromUri] DateTime? startDate = null,[FromUri] DateTime? endDate = null)
{
var logTimePeriod = GetTimePeriod(startDate, endDate);
//We will need to stop the request if trying to do this on a 1GB file
if (CanViewLogs() == false)
if (CanViewLogs(logTimePeriod) == false)
{
throw new HttpResponseException(Request.CreateNotificationValidationErrorResponse("Unable to view logs, due to size"));
}
var direction = orderDirection == "Descending" ? Direction.Descending : Direction.Ascending;
return _logViewer.GetLogs(startDate: DateTime.Now.AddDays(-1), endDate: DateTime.Now, filterExpression: filterExpression, pageNumber: pageNumber, orderDirection: direction, logLevels: logLevels);
return _logViewer.GetLogs(logTimePeriod, filterExpression: filterExpression, pageNumber: pageNumber, orderDirection: direction, logLevels: logLevels);
}
private static LogTimePeriod GetTimePeriod(DateTime? startDate, DateTime? endDate)
{
if (startDate == null || endDate == null)
{
var now = DateTime.Now;
if (startDate == null)
{
startDate = now.AddDays(-1);
}
if (endDate == null)
{
endDate = now;
}
}
return new LogTimePeriod(startDate.Value, endDate.Value);
}
[HttpGet]