Skip to content

Commit ab12a57

Browse files
authored
Merge pull request #38 from vonhoff/37-feat-toggle-for-json-pretty-printing
Add pretty-print JSON support to RichTextBox sink
2 parents 4a770d9 + c13562e commit ab12a57

30 files changed

+1219
-335
lines changed

.github/FUNDING.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
github: vonhoff
2+
ko_fi: vonhoff

.github/PULL_REQUEST_TEMPLATE.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<!-- Summarize your changes in the title -->
22

3-
**Motivation and Context**
3+
**Context**
44

55
<!-- Why is this change needed? Link any relevant issues. -->
66

.github/workflows/build.yml

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -9,29 +9,29 @@ on:
99
jobs:
1010
build-and-test:
1111
runs-on: windows-latest
12-
12+
1313
steps:
14-
- uses: actions/checkout@v3
15-
14+
- uses: actions/checkout@v4
15+
1616
- name: Setup .NET 8.0
17-
uses: actions/setup-dotnet@v3
17+
uses: actions/setup-dotnet@v5
1818
with:
1919
dotnet-version: 8.0.x
20-
20+
2121
- name: Setup MSBuild
22-
uses: microsoft/setup-msbuild@v1.1
23-
22+
uses: microsoft/setup-msbuild@v2
23+
2424
- name: Restore dependencies
2525
run: dotnet restore
26-
26+
2727
- name: Build
2828
run: dotnet build --no-restore --configuration Release --framework net8.0-windows
29-
29+
3030
- name: Test with Coverage
3131
run: dotnet test --no-build --configuration Release --framework net8.0-windows --collect:"XPlat Code Coverage" --results-directory ./coverage
3232

3333
- name: Generate coverage report
34-
uses: danielpalme/ReportGenerator-GitHub-Action@5.1.4
34+
uses: danielpalme/ReportGenerator-GitHub-Action@v5
3535
with:
3636
reports: './coverage/**/coverage.cobertura.xml'
3737
targetdir: './coverage/report'
@@ -50,7 +50,7 @@ jobs:
5050
$coverage = Select-Xml -Path "./coverage/**/coverage.cobertura.xml" -XPath "//coverage/@line-rate" | Select-Object -ExpandProperty Node | Select-Object -ExpandProperty Value
5151
$coveragePercent = [math]::Round([double]$coverage * 100, 2)
5252
Write-Host "Current line coverage: $coveragePercent%"
53-
if ($coveragePercent -lt 75) {
54-
Write-Error "Code coverage ($coveragePercent%) is below the required threshold of 75%"
53+
if ($coveragePercent -lt 80) {
54+
Write-Error "Code coverage ($coveragePercent%) is below the required threshold of 80%"
5555
exit 1
5656
}

CODE_OF_CONDUCT.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ a project may be further defined and clarified by project maintainers.
5555
## Enforcement
5656

5757
Instances of abusive, harassing, or otherwise unacceptable behavior may be
58-
reported by contacting the project team at `simon.vonhoff[at]outlook.com`. All
58+
reported by contacting the project team at `simon.vonhoff@outlook.com`. All
5959
complaints will be reviewed and investigated and will result in a response that
6060
is deemed necessary and appropriate to the circumstances. The project team is
6161
obligated to maintain confidentiality with regard to the reporter of an incident.

Demo/Form1.Designer.cs

Lines changed: 57 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Demo/Form1.cs

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,9 @@ public partial class Form1 : Form
3535
private RichTextBoxSinkOptions? _options;
3636
private RichTextBoxSink? _sink;
3737
private bool _toolbarsVisible = true;
38+
private bool _prettyPrintJson = false;
39+
private int _spacesPerIndent = 2;
40+
private bool _updatingIndent = false;
3841

3942
public Form1()
4043
{
@@ -47,7 +50,9 @@ private void Initialize()
4750
_options = new RichTextBoxSinkOptions(
4851
theme: ThemePresets.Literate,
4952
outputTemplate: "[{Timestamp:HH:mm:ss} {Level:u3}] {Message:l}{NewLine}{Exception}",
50-
formatProvider: new CultureInfo("en-US"));
53+
formatProvider: new CultureInfo("en-US"),
54+
prettyPrintJson: _prettyPrintJson,
55+
spacesPerIndent: _spacesPerIndent);
5156

5257
_sink = new RichTextBoxSink(richTextBox1, _options);
5358
Log.Logger = new LoggerConfiguration()
@@ -77,6 +82,15 @@ private void Initialize()
7782

7883
Log.Debug("Started logger.");
7984
btnDispose.Enabled = true;
85+
btnPrettyPrint.Text = _prettyPrintJson ? "Disable Pretty Print" : "Enable Pretty Print";
86+
87+
// Update the numeric up/down control without triggering events
88+
_updatingIndent = true;
89+
if (numericUpDownSpacesPerIndent.Value != _spacesPerIndent)
90+
{
91+
numericUpDownSpacesPerIndent.Value = _spacesPerIndent;
92+
}
93+
_updatingIndent = false;
8094
}
8195

8296
private void Form1_Load(object sender, EventArgs e)
@@ -350,6 +364,41 @@ private void btnAutoScroll_Click(object sender, EventArgs e)
350364
btnAutoScroll.Text = _options.AutoScroll ? "Disable Auto Scroll" : "Enable Auto Scroll";
351365
}
352366

367+
private void btnPrettyPrint_Click(object sender, EventArgs e)
368+
{
369+
_prettyPrintJson = !_prettyPrintJson;
370+
btnPrettyPrint.Text = _prettyPrintJson ? "Disable Pretty Print" : "Enable Pretty Print";
371+
372+
// Recreate the sink and logger with new pretty print setting
373+
CloseAndFlush();
374+
Initialize();
375+
376+
Log.Information("Pretty print JSON: {PrettyPrint}", _prettyPrintJson);
377+
}
378+
379+
private void numericUpDownSpacesPerIndent_ValueChanged(object sender, EventArgs e)
380+
{
381+
// Prevent recursive calls when we're updating the value programmatically
382+
if (_updatingIndent)
383+
{
384+
return;
385+
}
386+
387+
var newValue = (int)numericUpDownSpacesPerIndent.Value;
388+
if (newValue == _spacesPerIndent)
389+
{
390+
return;
391+
}
392+
393+
_spacesPerIndent = newValue;
394+
395+
// Recreate the sink and logger with new indent size
396+
CloseAndFlush();
397+
Initialize();
398+
399+
Log.Information("Spaces per indent changed to: {SpacesPerIndent}", _spacesPerIndent);
400+
}
401+
353402
private void Form1_KeyDown(object sender, KeyEventArgs e)
354403
{
355404
if (e.Control && e.KeyCode == Keys.T)

README.md

Lines changed: 28 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,10 @@ A [Serilog](https://github.com/serilog/serilog) sink that writes log events to a
1515
- Multiple theme presets with customization options
1616
- High-performance asynchronous processing
1717
- Line limit to control memory usage
18+
- Support for pretty-printing of JSON objects
1819
- WCAG compliant color schemes based on the [Serilog WPF RichTextBox](https://github.com/serilog-contrib/serilog-sinks-richtextbox) sink.
1920

20-
## Get Started
21+
## Getting Started
2122

2223
Install the package from NuGet:
2324

@@ -52,38 +53,47 @@ Log.Information("Hello, world!");
5253

5354
See the [Extension Method](Serilog.Sinks.RichTextBox.WinForms.Colored/RichTextBoxSinkLoggerConfigurationExtensions.cs) for more configuration options.
5455

56+
## Configuration Options
57+
58+
| Option | Description | Default Value |
59+
|-------------------|------------------------------------------------------------------------------------------------------------------------------|----------------------------------------------------------------------|
60+
| `theme` | The color theme applied when rendering individual message tokens. | `ThemePresets.Literate` |
61+
| `autoScroll` | When `true` (default) the target control scrolls automatically to the most recent log line. | `true` |
62+
| `maxLogLines` | Maximum number of log events retained in the in-memory circular buffer and rendered in the control. | `256` |
63+
| `outputTemplate` | Serilog output template that controls textual formatting of each log event. | `[{Timestamp:HH:mm:ss} {Level:u3}] {Message:lj}{NewLine}{Exception}` |
64+
| `formatProvider` | Optional culture-specific or custom formatting provider used when rendering scalar values; `null` for the invariant culture. | `CultureInfo.InvariantCulture` |
65+
| `prettyPrintJson` | When `true`, formats JSON values with indentation and line breaks for better readability. | `false` |
66+
| `spacesPerIndent` | Number of spaces per indentation level when pretty printing JSON. | `2` |
67+
5568
## Themes
5669

5770
Available built-in themes:
5871

59-
| Theme | Description |
60-
|-----------------------------|------------------------------------------------------------------------------|
61-
| `ThemePresets.Literate` | Styled to replicate the default theme of Serilog.Sinks.Console __(default)__ |
62-
| `ThemePresets.Grayscale` | A theme using only shades of gray, white, and black |
63-
| `ThemePresets.Colored` | A theme based on the original Serilog.Sinks.ColoredConsole sink |
64-
| `ThemePresets.Luminous` | A light theme with high contrast for accessibility |
72+
| Theme | Description |
73+
|--------------------------|------------------------------------------------------------------------------|
74+
| `ThemePresets.Literate` | Styled to replicate the default theme of Serilog.Sinks.Console __(default)__ |
75+
| `ThemePresets.Grayscale` | A theme using only shades of gray, white, and black |
76+
| `ThemePresets.Colored` | A theme based on the original Serilog.Sinks.ColoredConsole sink |
77+
| `ThemePresets.Luminous` | A light theme with high contrast for accessibility |
6578

6679
The themes based on the original sinks are slightly adjusted to be [WCAG compliant](https://www.w3.org/WAI/WCAG22/Understanding/contrast-minimum), ensuring that the contrast ratio between text and background colors is at least 4.5:1.
6780

6881
You can create your own custom themes by creating a new instance of the [Theme](Serilog.Sinks.RichTextBox.WinForms.Colored/Sinks/RichTextBoxForms/Themes/Theme.cs) class and passing it to the `RichTextBox` extension method. Look at the [existing themes](Serilog.Sinks.RichTextBox.WinForms.Colored/Sinks/RichTextBoxForms/Themes/ThemePresets.cs) for examples.
6982

70-
## Frequently Asked Questions
71-
72-
### Why is the package name so long?
83+
## Support the Project 💖
7384

74-
Shorter alternatives were already reserved in the NuGet registry, so a more descriptive name was needed for this implementation. The name is a bit long, but it makes it easier to find the package in the NuGet registry.
85+
This project has been maintained since 2022 and is still under active development. If you find it useful, please consider supporting it. Your support will help keep the project alive and allow me to dedicate more time to making improvements. You can support it through:
7586

76-
### Why use a WinForms RichTextBox instead of a WPF RichTextBox?
87+
* [GitHub Sponsors](https://github.com/sponsors/vonhoff)
88+
* [Ko-fi](https://ko-fi.com/vonhoff)
7789

78-
This sink is specifically designed for WinForms applications to avoid the WPF framework. Using a WPF-based logging component would require adding the entire WPF framework with all its dependencies, greatly increasing the size of the application.
90+
Every contribution of any size helps sustain ongoing development.
7991

80-
## Support and Contribute
92+
## Contributing
8193

82-
If you find value in this project, there are several ways you can contribute:
94+
Contributions are welcome! Report issues, improve documentation, or submit pull requests.
8395

84-
- Give the [project](https://github.com/vonhoff/Serilog.Sinks.RichTextBox.WinForms.Colored) a star on GitHub ⭐
85-
- Support the project through [GitHub Sponsors](https://github.com/sponsors/vonhoff)
86-
- Improve docs, report bugs, or submit PRs (see [CONTRIBUTING.md](CONTRIBUTING.md))
96+
See [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines.
8797

8898
## License
8999

SECURITY.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
## Reporting a Vulnerability
44

5-
If you find a security issue, please email `simon.vonhoff[at]outlook.com` with a description. Include a suggested fix if you have one.
5+
If you find a security issue, please email `simon.vonhoff@outlook.com` with a description. Include a suggested fix if you have one.
66

77
We will review the report, release a fix or mitigation if needed, and credit you. Do **not** disclose the issue publicly until a fix is released. Once addressed, public disclosure is allowed.
88

0 commit comments

Comments
 (0)