Skip to content

feat(#130): render exception as a string property type #135

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

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 1 addition & 0 deletions samples/WebApi/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
})
.WithName("GetWeatherForecast")
.WithOpenApi();
app.MapGet("/exception", () => { throw new InvalidOperationException("This route doesn't exist!"); });

app.Run();

Expand Down
6 changes: 3 additions & 3 deletions samples/WebApi/WebApi.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,9 @@
<!-- Serilog UI packages -->
<ItemGroup>
<!-- comment/uncomment to directly reference Nuget release
<PackageReference Include="Serilog.UI" Version="3.0.1"/>
<PackageReference Include="Serilog.UI.MsSqlServerProvider" Version="3.0.0"/>
<PackageReference Include="Serilog.UI.ElasticSearchProvider" Version="3.0.0"/>
<PackageReference Include="Serilog.UI" Version="3.1.0"/>
<PackageReference Include="Serilog.UI.MsSqlServerProvider" Version="3.1.0"/>
<PackageReference Include="Serilog.UI.ElasticSearchProvider" Version="3.1.0"/>
-->

<!-- comment/uncomment to directly reference solution projects -->
Expand Down
4 changes: 2 additions & 2 deletions samples/WebApp/WebApp.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,8 @@
<!-- Serilog UI packages -->
<ItemGroup>
<!-- comment/uncomment to directly reference Nuget release
<PackageReference Include="Serilog.UI" Version="3.0.1"/>
<PackageReference Include="Serilog.UI.MongoDbProvider" Version="3.0.0"/>
<PackageReference Include="Serilog.UI" Version="3.1.0"/>
<PackageReference Include="Serilog.UI.MongoDbProvider" Version="3.1.0"/>
-->

<!-- comment/uncomment to directly reference solution projects -->
Expand Down
6 changes: 6 additions & 0 deletions src/Serilog.Ui.Core/Interfaces/ISerilogUiOptionsBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,10 @@ public interface ISerilogUiOptionsBuilder
/// <param name="providerKey">The IDataProvider <see cref="IDataProvider.Name"/>.</param>
/// <typeparam name="T"></typeparam>
void RegisterColumnsInfo<T>(string providerKey) where T : LogModel;

/// <summary>
/// Register a Provider Key Name that saves the Exception field as string.
/// </summary>
/// <param name="providerKey">The IDataProvider <see cref="IDataProvider.Name"/>.</param>
void RegisterExceptionAsStringForProviderKey(string providerKey);
}
12 changes: 12 additions & 0 deletions src/Serilog.Ui.Core/Models/Options/ProvidersOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ public class ProvidersOptions

private readonly HashSet<string> _disabledSortProviderNames = [];

private readonly HashSet<string> _exceptionAsStringProviderNames = [];

/// <summary>
/// Gets the AdditionalColumns.
/// </summary>
Expand All @@ -25,6 +27,11 @@ public class ProvidersOptions
/// </summary>
public IEnumerable<string> DisabledSortProviderNames => _disabledSortProviderNames.ToList().AsReadOnly();

/// <summary>
/// Gets the ExceptionAsStringProviderNames.
/// </summary>
public IEnumerable<string> ExceptionAsStringProviderNames => _exceptionAsStringProviderNames.ToList().AsReadOnly();

internal void RegisterType<T>(string providerKey)
where T : LogModel
{
Expand All @@ -35,4 +42,9 @@ internal void RegisterDisabledSortName(string name)
{
_disabledSortProviderNames.Add(name);
}

internal void RegisterExceptionAsStringProvider(string name)
{
_exceptionAsStringProviderNames.Add(name);
}
}
6 changes: 6 additions & 0 deletions src/Serilog.Ui.Core/OptionsBuilder/SerilogUiOptionsBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,12 @@ public void RegisterColumnsInfo<T>(string providerKey) where T : LogModel
_providersOptions.RegisterType<T>(providerKey);
}

/// <inheritdoc />
public void RegisterExceptionAsStringForProviderKey(string providerKey)
{
_providersOptions.RegisterExceptionAsStringProvider(providerKey);
}

/// <summary>
/// Register the <see cref="ProvidersOptions"/> in <see cref="IServiceCollection"/>.
/// </summary>
Expand Down
2 changes: 1 addition & 1 deletion src/Serilog.Ui.Core/Serilog.Ui.Core.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<TargetFramework>netstandard2.0</TargetFramework>
<GenerateDocumentationFile>True</GenerateDocumentationFile>
<LangVersion>latest</LangVersion>
<Version>3.0.0</Version>
<Version>3.1.0</Version>
</PropertyGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

<TargetFramework>netstandard2.0</TargetFramework>
<LangVersion>latest</LangVersion>
<Version>3.0.0</Version>
<Version>3.1.0</Version>

<Authors>Ricardo Demauro - rmauro.dev</Authors>
<Description>ElasticSearch data provider for Serilog UI.</Description>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<PackageId>Serilog.UI.MongoDbProvider</PackageId>
<TargetFramework>netstandard2.0</TargetFramework>
<LangVersion>latest</LangVersion>
<Version>3.0.0</Version>
<Version>3.1.0</Version>

<Authors>Christian Haase</Authors>
<Description>MongoDB data provider for Serilog UI.</Description>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,12 +43,15 @@ public static ISerilogUiOptionsBuilder UseSqlServer<T>(
setupOptions(dbOptions);
dbOptions.Validate();

var providerName = dbOptions.GetProviderName(SqlServerDataProvider.MsSqlProviderName);

optionsBuilder.RegisterExceptionAsStringForProviderKey(providerName);
SqlMapper.AddTypeHandler(new DapperDateTimeHandler(dateTimeCustomParsing));

var customModel = typeof(T) != typeof(SqlServerLogModel);
if (customModel)
{
optionsBuilder.RegisterColumnsInfo<T>(dbOptions.GetProviderName(SqlServerDataProvider.MsSqlProviderName));
optionsBuilder.RegisterColumnsInfo<T>(providerName);
optionsBuilder.Services.AddScoped<IDataProvider>(_ => new SqlServerDataProvider<T>(dbOptions));

return optionsBuilder;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

<TargetFramework>netstandard2.0</TargetFramework>
<LangVersion>latest</LangVersion>
<Version>3.0.0</Version>
<Version>3.1.0</Version>

<Description>Microsoft SQL Server data provider for Serilog UI.</Description>
<PackageTags>serilog serilog-ui serilog.sinks.mssqlserver mssqlserver</PackageTags>
Expand Down
4 changes: 2 additions & 2 deletions src/Serilog.Ui.MsSqlServerProvider/SqlServerDataProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -124,13 +124,13 @@ private void GenerateWhereClause(StringBuilder queryBuilder, FetchLogsQuery quer
{
var conditionStart = "WHERE";

if (!string.IsNullOrEmpty(queryParams.Level))
if (!string.IsNullOrWhiteSpace(queryParams.Level))
{
queryBuilder.Append($"{conditionStart} [{ColumnLevelName}] = @Level ");
conditionStart = "AND";
}

if (!string.IsNullOrEmpty(queryParams.SearchCriteria))
if (!string.IsNullOrWhiteSpace(queryParams.SearchCriteria))
{
queryBuilder.Append($"{conditionStart} [{ColumnMessageName}] LIKE @Search {SearchCriteriaWhereQuery()} ");
conditionStart = "AND";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@ Action<RelationalDbOptions> setupOptions
setupOptions(dbOptions);
dbOptions.Validate();

var providerName = dbOptions.GetProviderName(MySqlDataProvider.MySqlProviderName);

optionsBuilder.RegisterExceptionAsStringForProviderKey(providerName);

optionsBuilder.Services.AddScoped<IDataProvider, MySqlDataProvider>(_ => new MySqlDataProvider(dbOptions));

return optionsBuilder;
Expand Down Expand Up @@ -61,10 +65,14 @@ Action<RelationalDbOptions> setupOptions
setupOptions(dbOptions);
dbOptions.Validate();

var providerName = dbOptions.GetProviderName(MariaDbDataProvider.ProviderName);

optionsBuilder.RegisterExceptionAsStringForProviderKey(providerName);

var customModel = typeof(T) != typeof(MySqlLogModel);
if (customModel)
{
optionsBuilder.RegisterColumnsInfo<T>(dbOptions.GetProviderName(MariaDbDataProvider.ProviderName));
optionsBuilder.RegisterColumnsInfo<T>(providerName);
optionsBuilder.Services.AddScoped<IDataProvider>(_ => new MariaDbDataProvider<T>(dbOptions));
return optionsBuilder;
}
Expand Down
3 changes: 2 additions & 1 deletion src/Serilog.Ui.MySqlProvider/MySqlDataProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,6 @@ protected override string SelectQuery

protected override string SearchCriteriaWhereQuery() => "OR Exception LIKE @Search";

public override string Name => Options.GetProviderName("MySQL");
internal const string MySqlProviderName = "MySQL";
public override string Name => Options.GetProviderName(MySqlProviderName);
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<PackageId>Serilog.UI.MySqlProvider</PackageId>
<TargetFramework>netstandard2.0</TargetFramework>
<LangVersion>latest</LangVersion>
<Version>3.0.0</Version>
<Version>3.1.0</Version>

<Description>MySQL and MariaDB data provider for Serilog UI.</Description>
<PackageTags>serilog serilog-ui serilog.sinks.mysql serilog.sinks.mariadb</PackageTags>
Expand Down
4 changes: 2 additions & 2 deletions src/Serilog.Ui.MySqlProvider/Shared/DataProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -114,13 +114,13 @@ private void GenerateWhereClause(StringBuilder queryBuilder, FetchLogsQuery quer
{
var conditionStart = "WHERE";

if (!string.IsNullOrEmpty(queryParams.Level))
if (!string.IsNullOrWhiteSpace(queryParams.Level))
{
queryBuilder.Append($"WHERE {ColumnLevelName} = @Level ");
conditionStart = "AND";
}

if (!string.IsNullOrEmpty(queryParams.SearchCriteria))
if (!string.IsNullOrWhiteSpace(queryParams.SearchCriteria))
{
queryBuilder.Append($"{conditionStart} ({ColumnMessageName} LIKE @Search {SearchCriteriaWhereQuery()}) ");
conditionStart = "AND";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,14 @@ Action<PostgreSqlDbOptions> setupOptions
setupOptions(dbOptions);
dbOptions.Validate();

var providerName = dbOptions.GetProviderName(PostgresDataProvider.ProviderName);

optionsBuilder.RegisterExceptionAsStringForProviderKey(providerName);

var customModel = typeof(T) != typeof(PostgresLogModel);
if (customModel)
{
optionsBuilder.RegisterColumnsInfo<T>(dbOptions.GetProviderName(PostgresDataProvider.ProviderName));
optionsBuilder.RegisterColumnsInfo<T>(providerName);
optionsBuilder.Services.AddScoped<IDataProvider>(_ => new PostgresDataProvider<T>(dbOptions));

return optionsBuilder;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<PackageId>Serilog.UI.PostgreSqlProvider</PackageId>
<TargetFramework>netstandard2.0</TargetFramework>
<LangVersion>latest</LangVersion>
<Version>3.0.0</Version>
<Version>3.1.0</Version>

<GenerateDocumentationFile>True</GenerateDocumentationFile>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<PackageId>Serilog.Ui.RavenDbProvider</PackageId>
<TargetFramework>netstandard2.0</TargetFramework>
<LangVersion>latest</LangVersion>
<Version>2.0.0</Version>
<Version>2.1.0</Version>

<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
Expand Down
1 change: 1 addition & 0 deletions src/Serilog.Ui.Web/Endpoints/SerilogUiAppRoutes.cs
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ private async Task<string> LoadStream(Stream stream, UiOptions options)
authType,
options.ColumnsInfo,
options.DisabledSortOnKeys,
options.RenderExceptionAsStringKeys,
options.ShowBrand,
options.HomeUrl,
BlockHomeAccess,
Expand Down
5 changes: 5 additions & 0 deletions src/Serilog.Ui.Web/Models/UiOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,11 @@ internal void Validate()
/// </summary>
internal IEnumerable<string> DisabledSortOnKeys { get; } = options.DisabledSortProviderNames;

/// <summary>
/// Gets or sets the database keys that renders exceptions as simple strings.
/// </summary>
internal IEnumerable<string> RenderExceptionAsStringKeys { get; } = options.ExceptionAsStringProviderNames;

/// <summary>
/// Gets or sets the head content, a string that will be placed in the &lt;head&gt; of the index.html
/// </summary>
Expand Down
4 changes: 2 additions & 2 deletions src/Serilog.Ui.Web/Serilog.Ui.Web.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<PackageId>Serilog.UI</PackageId>
<TargetFrameworks>net6.0;net7.0;net8.0</TargetFrameworks>
<LangVersion>latest</LangVersion>
<Version>3.0.1</Version>
<Version>3.1.0</Version>
</PropertyGroup>

<ItemGroup>
Expand Down Expand Up @@ -35,4 +35,4 @@
<_Parameter1>DynamicProxyGenAssembly2</_Parameter1>
</AssemblyAttribute>
</ItemGroup>
</Project>
</Project>
1 change: 1 addition & 0 deletions src/Serilog.Ui.Web/src/__tests__/_setup/testing-utils.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ const Wrapper = ({
homeUrl: 'https://test-google.com',
columnsInfo,
disabledSortOnKeys: ['disabled-sort-db'],
renderExceptionAsStringKeys: ['exception-string-sample'],
})}
</div>

Expand Down
41 changes: 41 additions & 0 deletions src/Serilog.Ui.Web/src/__tests__/hooks/useException.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { renderHook } from '__tests__/_setup/testing-utils';
import { useException } from 'app/hooks/useException';
import { describe, expect, it, vi } from 'vitest';

const mockForm = {
watch: vi.fn(),
getValues: vi.fn(),
};
const mockColInfo = { removeException: vi.fn() };
vi.mock('../../app/hooks/useSearchForm', () => ({
useSearchForm: () => mockForm,
}));
vi.mock('../../app/hooks/useColumnsInfo', () => ({
useColumnsInfo: () => mockColInfo,
}));

describe('useException', () => {
it('returns properties untouched', () => {
mockForm.getValues.mockImplementation(() => 'test-db');
mockForm.watch.mockImplementation(() => 'test-db');

const { result } = renderHook(() => useException('my-string untouched', 'log'));

expect(result.current.logType).toBe('log');
expect(result.current.exceptionContent).toBe('my-string untouched');
});

it('returns string type, with modified content', () => {
mockForm.getValues.mockImplementation(() => 'exception-string-sample');
mockForm.watch.mockImplementation(() => 'exception-string-sample');
mockColInfo.removeException.mockReturnValue(true);

const { result } = renderHook(() =>
useException('my-string modified with at sample', 'log'),
);

expect(result.current.removeException).toBeTruthy();
expect(result.current.logType).toBe('string');
expect(result.current.exceptionContent).toBe('my-string modified with at sample');
});
});
19 changes: 17 additions & 2 deletions src/Serilog.Ui.Web/src/app/components/Table/CodeContent.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { Box, Loader } from '@mantine/core';
import { Box, Loader, Textarea } from '@mantine/core';
import { renderCodeContent } from 'app/util/prettyPrints';
import { useEffect, useState } from 'react';
import classes from 'style/table.module.css';
import { LogType } from 'types/types';
import { CopySection } from '../Util/Copy';

const CodeContent = ({ content, codeType }: { content: string; codeType: LogType }) => {
const [codeContent, setCodeContent] = useState<TrustedHTML>('');
Expand All @@ -26,10 +27,24 @@ const CodeContent = ({ content, codeType }: { content: string; codeType: LogType
</Box>
);

if ((codeType as unknown as string) === 'string')
return (
<Textarea
autosize
value={codeContent as string}
disabled
rightSectionPointerEvents="all"
rightSection={<CopySection value={codeContent as string} />}
minRows={1}
maxRows={20}
classNames={{ input: classes.modalTextAreaInputWrapper }}
/>
);

return (
<div
dangerouslySetInnerHTML={{ __html: codeContent }}
className={classes.detailModalCode}
className={classes.modalCode}
></div>
);
};
Expand Down
Loading
Loading