Skip to content

Add a SORT-BY option to the UI #41

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
75c6886
add sort option on the frontend
followynne Jan 9, 2022
a1d3b2c
implement sort params in IDataProvider
followynne Jan 9, 2022
1e5384c
implement mongodb driver sort option
followynne Jan 9, 2022
21d197c
add params without implementation for other providers
followynne Jan 9, 2022
ea996b9
add built version, add middleware params
followynne Jan 9, 2022
2b1e9f4
convert utc to timestamp to use shared prop
followynne Jan 9, 2022
0c99feb
sort implementation for sql-like
followynne Jan 9, 2022
2e6f110
Merge branch 'feature/refactor-assets-structure' into feature/add-sor…
followynne Jan 9, 2022
a6b1a18
rename timestamp enum, add elastic implementation
followynne Jan 9, 2022
993181a
Merge branch 'feature/refactor-assets-structure' into feature/add-sor…
followynne Jan 9, 2022
d833c69
npm bump
followynne Jan 11, 2022
3994393
add on fe new sort options
followynne Jan 11, 2022
96e26ec
add on be new options, refactor sql sort commands
followynne Jan 11, 2022
304be4e
commit updated bundled version
matteo-gregoricchio-deltatre Jan 11, 2022
7d348f0
Merge branch 'feature/refactor-assets' into feature/add-sortable-options
followynne Feb 6, 2022
66e3ddb
chore(build): bump
followynne Feb 6, 2022
0724598
Merge branch 'mo-esmp:dev' into feature/add-sort-options
followynne Feb 6, 2022
897bc2a
add sort option on the frontend
followynne Jan 9, 2022
d07cb9f
implement sort params in IDataProvider
followynne Jan 9, 2022
0d6a4bb
implement mongodb driver sort option
followynne Jan 9, 2022
8241c10
add params without implementation for other providers
followynne Jan 9, 2022
ea78c5b
add built version, add middleware params
followynne Jan 9, 2022
3882143
convert utc to timestamp to use shared prop
followynne Jan 9, 2022
b26c977
sort implementation for sql-like
followynne Jan 9, 2022
b94da02
rename timestamp enum, add elastic implementation
followynne Jan 9, 2022
9b3ff26
Merge branch 'feature/refactor-assets-structure' into feature/add-sor…
followynne Jan 9, 2022
3818f6e
add on fe new sort options
followynne Jan 11, 2022
a98241c
add on be new options, refactor sql sort commands
followynne Jan 11, 2022
acb7782
commit updated bundled version
matteo-gregoricchio-deltatre Jan 11, 2022
43ca40a
chore(build): bump
followynne Feb 6, 2022
81909e0
Merge branch 'feature/add-sort-options' of https://github.com/followy…
followynne May 7, 2022
4a7c673
Merge branch 'master' into feature/add-sortable-options
followynne Aug 16, 2022
36b38b3
fix(elastic-provider): sort function on Text fields, sort fluent-comp…
followynne Aug 17, 2022
13dc3c2
fix: remove wrong committed file
followynne Aug 17, 2022
c6a90ae
Merge branch 'dev' into feat/add-sortable-options
followynne Sep 6, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion src/Serilog.Ui.Core/IDataProvider.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using static Serilog.Ui.Core.Models.SearchOptions;

namespace Serilog.Ui.Core
{
Expand All @@ -25,7 +26,9 @@ public interface IDataProvider
string level = null,
string searchCriteria = null,
DateTime? startDate = null,
DateTime? endDate = null
DateTime? endDate = null,
SortProperty sortOn = SortProperty.Timestamp,
SortDirection sortBy = SortDirection.Desc
);
}
}
17 changes: 17 additions & 0 deletions src/Serilog.Ui.Core/Models/SearchOptions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
namespace Serilog.Ui.Core.Models
{
public class SearchOptions
{
public enum SortProperty
{
Timestamp,
Level,
Message
}
public enum SortDirection
{
Asc,
Desc
}
}
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
using Nest;
using Newtonsoft.Json;
using Serilog.Ui.Core;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Threading;
using System.Threading.Tasks;
using static Serilog.Ui.Core.Models.SearchOptions;

namespace Serilog.Ui.ElasticSearchProvider
{
Expand All @@ -25,9 +29,11 @@ public ElasticSearchDbDataProvider(IElasticClient client, ElasticSearchDbOptions
string level = null,
string searchCriteria = null,
DateTime? startDate = null,
DateTime? endDate = null)
DateTime? endDate = null,
SortProperty sortOn = SortProperty.Timestamp,
SortDirection sortBy = SortDirection.Desc)
{
return GetLogsAsync(page - 1, count, level, searchCriteria, startDate, endDate);
return GetLogsAsync(page - 1, count, level, searchCriteria, startDate, endDate, sortOn, sortBy);
}

private async Task<(IEnumerable<LogModel>, int)> GetLogsAsync(
Expand All @@ -37,18 +43,28 @@ public ElasticSearchDbDataProvider(IElasticClient client, ElasticSearchDbOptions
string searchCriteria,
DateTime? startDate = null,
DateTime? endDate = null,
SortProperty sortOn = SortProperty.Timestamp,
SortDirection sortBy = SortDirection.Desc,
CancellationToken cancellationToken = default)
{
// get the PropertyInfo for the Sorted property
var sortProperty = typeof(ElasticSearchDbLogModel).GetProperty(sortOn.ToString());
// get the actual PropertyName used by Elastic, that was set in the JsonAttribute
var jsonAttrName = sortProperty.GetCustomAttribute<JsonPropertyAttribute>().PropertyName;

var descriptor = new SearchDescriptor<ElasticSearchDbLogModel>()
.Index(_options.IndexName)
.Sort(m => m.Descending(f => f.Timestamp))
.Size(count)
.Skip(page * count)
.Query(q =>
+q.Match(m => m.Field(f => f.Level).Query(level)) &&
+q.DateRange(dr => dr.Field(f => f.Timestamp).GreaterThanOrEquals(startDate).LessThanOrEquals(endDate)) &&
+q.Match(m => m.Field(f => f.Message).Query(searchCriteria)) ||
+q.Match(m => m.Field(f => f.Exceptions).Query(searchCriteria)));
+q.Match(m => m.Field(f => f.Exceptions).Query(searchCriteria)))
.Sort(m => m.Field(
// to manage Text fields (pass throught .keyword)
sortProperty.PropertyType == typeof(string) ? $"{jsonAttrName}.keyword" : jsonAttrName,
sortBy == SortDirection.Desc ? SortOrder.Descending : SortOrder.Ascending))
.Skip(page * count)
.Size(count);

var result = await _client.SearchAsync<ElasticSearchDbLogModel>(descriptor, cancellationToken);

Expand Down
30 changes: 22 additions & 8 deletions src/Serilog.Ui.MongoDbProvider/MongoDbDataProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Threading.Tasks;
using static Serilog.Ui.Core.Models.SearchOptions;

namespace Serilog.Ui.MongoDbProvider
{
Expand All @@ -17,7 +19,6 @@ public MongoDbDataProvider(IMongoClient client, MongoDbOptions options)
if (options is null) throw new ArgumentNullException(nameof(options));

_collection = client.GetDatabase(options.DatabaseName).GetCollection<MongoDbLogModel>(options.CollectionName);
var s = _collection.CollectionNamespace;
}

public async Task<(IEnumerable<LogModel>, int)> FetchDataAsync(
Expand All @@ -26,9 +27,11 @@ public MongoDbDataProvider(IMongoClient client, MongoDbOptions options)
string level = null,
string searchCriteria = null,
DateTime? startDate = null,
DateTime? endDate = null)
DateTime? endDate = null,
SortProperty sortOn = SortProperty.Timestamp,
Core.Models.SearchOptions.SortDirection sortBy = Core.Models.SearchOptions.SortDirection.Desc)
{
var logsTask = await GetLogsAsync(page - 1, count, level, searchCriteria, startDate, endDate);
var logsTask = await GetLogsAsync(page - 1, count, level, searchCriteria, startDate, endDate, sortOn, sortBy);
var logCountTask = await CountLogsAsync(level, searchCriteria, startDate, endDate);

//await Task.WhenAll(logsTask, logCountTask);
Expand All @@ -42,18 +45,29 @@ private async Task<IEnumerable<LogModel>> GetLogsAsync(
string level,
string searchCriteria,
DateTime? startDate,
DateTime? endDate)
DateTime? endDate,
SortProperty sortOn = SortProperty.Timestamp,
Core.Models.SearchOptions.SortDirection sortBy = Core.Models.SearchOptions.SortDirection.Desc)
{
try
{
var builder = Builders<MongoDbLogModel>.Filter.Empty;
GenerateWhereClause(ref builder, level, searchCriteria, startDate, endDate);

var logs = await _collection
.Find(builder)
var logsFind = _collection
.Find(builder);

var isDesc = sortBy == Core.Models.SearchOptions.SortDirection.Desc;
var sortPropertyName = typeof(MongoDbLogModel).GetProperty(sortOn.ToString()).Name;
// workaround to use utctimestamp
if (sortPropertyName.Equals(SortProperty.Timestamp.ToString())) sortPropertyName = nameof(MongoDbLogModel.UtcTimeStamp);
if (sortPropertyName.Equals(SortProperty.Message.ToString())) sortPropertyName = nameof(MongoDbLogModel.RenderedMessage);
SortDefinition<MongoDbLogModel> sortBuilder = isDesc ?
Builders<MongoDbLogModel>.Sort.Descending(sortPropertyName) :
Builders<MongoDbLogModel>.Sort.Ascending(sortPropertyName);
var logs = await
logsFind.Sort(sortBuilder)
.Skip(count * page)
.Limit(count)
.SortByDescending(entry => entry.Timestamp)
.ToListAsync();

var index = 1;
Expand Down
18 changes: 12 additions & 6 deletions src/Serilog.Ui.MsSqlServerProvider/SqlServerDataProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using System.Data;
using System.Text;
using System.Threading.Tasks;
using static Serilog.Ui.Core.Models.SearchOptions;

namespace Serilog.Ui.MsSqlServerProvider
{
Expand All @@ -24,10 +25,11 @@ public SqlServerDataProvider(RelationalDbOptions options)
string logLevel = null,
string searchCriteria = null,
DateTime? startDate = null,
DateTime? endDate = null
)
DateTime? endDate = null,
SortProperty sortOn = SortProperty.Timestamp,
SortDirection sortBy = SortDirection.Desc)
{
var logsTask = GetLogsAsync(page - 1, count, logLevel, searchCriteria, startDate, endDate);
var logsTask = GetLogsAsync(page - 1, count, logLevel, searchCriteria, startDate, endDate, sortOn, sortBy);
var logCountTask = CountLogsAsync(logLevel, searchCriteria, startDate, endDate);

await Task.WhenAll(logsTask, logCountTask);
Expand All @@ -41,7 +43,9 @@ private async Task<IEnumerable<LogModel>> GetLogsAsync(
string level,
string searchCriteria,
DateTime? startDate,
DateTime? endDate)
DateTime? endDate,
SortProperty sortOn = SortProperty.Timestamp,
SortDirection sortBy = SortDirection.Desc)
{
var queryBuilder = new StringBuilder();
queryBuilder.Append("SELECT [Id], [Message], [Level], [TimeStamp], [Exception], [Properties] FROM [");
Expand All @@ -52,7 +56,7 @@ private async Task<IEnumerable<LogModel>> GetLogsAsync(

GenerateWhereClause(queryBuilder, level, searchCriteria, startDate, endDate);

queryBuilder.Append("ORDER BY Id DESC OFFSET @Offset ROWS FETCH NEXT @Count ROWS ONLY");
queryBuilder.Append($"ORDER BY @SortOn @SortBy OFFSET @Offset ROWS FETCH NEXT @Count ROWS ONLY");

using (IDbConnection connection = new SqlConnection(_options.ConnectionString))
{
Expand All @@ -64,7 +68,9 @@ private async Task<IEnumerable<LogModel>> GetLogsAsync(
Level = level,
Search = searchCriteria != null ? "%" + searchCriteria + "%" : null,
StartDate = startDate,
EndDate = endDate
EndDate = endDate,
SortOn = sortOn.ToString(),
SortBy = sortBy.ToString().ToUpper()
});

var index = 1;
Expand Down
18 changes: 12 additions & 6 deletions src/Serilog.Ui.MySqlProvider/MySqlDataProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
using static Serilog.Ui.Core.Models.SearchOptions;

namespace Serilog.Ui.MySqlProvider
{
Expand All @@ -23,10 +24,11 @@ public MySqlDataProvider(RelationalDbOptions options)
string logLevel = null,
string searchCriteria = null,
DateTime? startDate = null,
DateTime? endDate = null
)
DateTime? endDate = null,
SortProperty sortOn = SortProperty.Timestamp,
SortDirection sortBy = SortDirection.Desc)
{
var logsTask = GetLogsAsync(page - 1, count, logLevel, searchCriteria, startDate, endDate);
var logsTask = GetLogsAsync(page - 1, count, logLevel, searchCriteria, startDate, endDate, sortOn, sortBy);
var logCountTask = CountLogsAsync(logLevel, searchCriteria, startDate, endDate);

await Task.WhenAll(logsTask, logCountTask);
Expand All @@ -40,7 +42,9 @@ private async Task<IEnumerable<LogModel>> GetLogsAsync(
string level,
string searchCriteria,
DateTime? startDate,
DateTime? endDate)
DateTime? endDate,
SortProperty sortOn = SortProperty.Timestamp,
SortDirection sortBy = SortDirection.Desc)
{
var queryBuilder = new StringBuilder();
queryBuilder.Append("SELECT Id, Message, LogLevel AS `Level`, TimeStamp, Exception, Properties From `");
Expand All @@ -49,7 +53,7 @@ private async Task<IEnumerable<LogModel>> GetLogsAsync(

GenerateWhereClause(queryBuilder, level, searchCriteria, startDate, endDate);

queryBuilder.Append("ORDER BY Id DESC LIMIT @Offset, @Count");
queryBuilder.Append($"ORDER BY @SortOn @SortBy LIMIT @Offset, @Count");

using (var connection = new MySqlConnection(_options.ConnectionString))
{
Expand All @@ -60,7 +64,9 @@ private async Task<IEnumerable<LogModel>> GetLogsAsync(
Level = level,
Search = searchCriteria != null ? $"%{searchCriteria}%" : null,
StartDate = startDate,
EndDate = endDate
EndDate = endDate,
SortOn = sortOn.ToString(),
SortBy = sortBy.ToString().ToUpper()
};
var logs = await connection.QueryAsync<MySqlLogModel>(queryBuilder.ToString(), param);
var index = 1;
Expand Down
18 changes: 12 additions & 6 deletions src/Serilog.Ui.PostgreSqlProvider/PostgreDataProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using System.Data;
using System.Text;
using System.Threading.Tasks;
using static Serilog.Ui.Core.Models.SearchOptions;

namespace Serilog.Ui.PostgreSqlProvider
{
Expand All @@ -24,10 +25,11 @@ public PostgresDataProvider(RelationalDbOptions options)
string logLevel = null,
string searchCriteria = null,
DateTime? startDate = null,
DateTime? endDate = null
)
DateTime? endDate = null,
SortProperty sortOn = SortProperty.Timestamp,
SortDirection sortBy = SortDirection.Desc)
{
var logsTask = GetLogsAsync(page - 1, count, logLevel, searchCriteria, startDate, endDate);
var logsTask = GetLogsAsync(page - 1, count, logLevel, searchCriteria, startDate, endDate, sortOn, sortBy);
var logCountTask = CountLogsAsync(logLevel, searchCriteria, startDate, endDate);

await Task.WhenAll(logsTask, logCountTask);
Expand All @@ -40,7 +42,9 @@ private async Task<IEnumerable<LogModel>> GetLogsAsync(int page,
string level,
string searchCriteria,
DateTime? startDate,
DateTime? endDate)
DateTime? endDate,
SortProperty sortOn = SortProperty.Timestamp,
SortDirection sortBy = SortDirection.Desc)
{
var queryBuilder = new StringBuilder();
queryBuilder.Append("SELECT message, message_template, level, timestamp, exception, log_event AS \"Properties\" FROM ");
Expand All @@ -50,7 +54,7 @@ private async Task<IEnumerable<LogModel>> GetLogsAsync(int page,

GenerateWhereClause(queryBuilder, level, searchCriteria, startDate, endDate);

queryBuilder.Append(" ORDER BY timestamp DESC LIMIT @Count OFFSET @Offset ");
queryBuilder.Append($" ORDER BY @SortOn @SortBy LIMIT @Count OFFSET @Offset ");

using IDbConnection connection = new NpgsqlConnection(_options.ConnectionString);
var logs = await connection.QueryAsync<PostgresLogModel>(queryBuilder.ToString(),
Expand All @@ -61,7 +65,9 @@ private async Task<IEnumerable<LogModel>> GetLogsAsync(int page,
Level = LogLevelConverter.GetLevelValue(level),
Search = searchCriteria != null ? "%" + searchCriteria + "%" : null,
StartDate = startDate,
EndDate = endDate
EndDate = endDate,
SortOn = sortOn.ToString().ToLower(),
SortBy = sortBy.ToString().ToUpper()
});

var index = 1;
Expand Down
7 changes: 6 additions & 1 deletion src/Serilog.Ui.Web/SerilogUiMiddleware.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using static Serilog.Ui.Core.Models.SearchOptions;

namespace Serilog.Ui.Web
{
Expand Down Expand Up @@ -146,13 +147,17 @@ private async Task<string> FetchLogsAsync(HttpContext httpContext)
{
httpContext.Request.Query.TryGetValue("page", out var pageStr);
httpContext.Request.Query.TryGetValue("count", out var countStr);
httpContext.Request.Query.TryGetValue("sorton", out var sortStrOn);
httpContext.Request.Query.TryGetValue("sortby", out var sortStrBy);
httpContext.Request.Query.TryGetValue("level", out var levelStr);
httpContext.Request.Query.TryGetValue("search", out var searchStr);
httpContext.Request.Query.TryGetValue("startDate", out var startDateStar);
httpContext.Request.Query.TryGetValue("endDate", out var endDateStar);

int.TryParse(pageStr, out var currentPage);
int.TryParse(countStr, out var count);
Enum.TryParse<SortProperty>(sortStrOn, out var sortProperty);
Enum.TryParse<SortDirection>(sortStrBy, out var sortDirection);

DateTime.TryParse(startDateStar, out var startDate);
DateTime.TryParse(endDateStar, out var endDate);
Expand All @@ -165,7 +170,7 @@ private async Task<string> FetchLogsAsync(HttpContext httpContext)

var provider = httpContext.RequestServices.GetService<IDataProvider>();
var (logs, total) = await provider.FetchDataAsync(currentPage, count, levelStr, searchStr,
startDate == default ? (DateTime?)null : startDate, endDate == default ? (DateTime?)null : endDate);
startDate == default ? (DateTime?)null : startDate, endDate == default ? (DateTime?)null : endDate, sortProperty, sortDirection);
//var result = JsonSerializer.Serialize(logs, _jsonSerializerOptions);
var result = JsonConvert.SerializeObject(new { logs, total, count, currentPage }, _jsonSerializerOptions);
return result;
Expand Down
15 changes: 15 additions & 0 deletions src/Serilog.Ui.Web/assets/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,21 @@ <h5 class="modal-title" id="loginModalLabel">JWT Authorizations</h5>
</label>
</div>
</div>
<div class="col col-auto">
<div class="table-select" id="logSort">
<label>
Sort
<select id="sortSerilogUi" name="sortSerilogUi" class="form-control form-control-sm">
<option value="Timestamp" data-direction="Desc" selected="selected">by TimeStamp DESC</option>
<option value="Timestamp" data-direction="Asc">by TimeStamp ASC</option>
<option value="Level" data-direction="Desc">by Level DESC</option>
<option value="Level" data-direction="Asc">by Level ASC</option>
<option value="Message" data-direction="Desc">by Message DESC</option>
<option value="Message" data-direction="Asc">by Message ASC</option>
</select>
</label>
</div>
</div>
<div class="col col-auto">
<div class="table-select" id="logFilter">
<label>
Expand Down
Loading