1- // Copyright 2017 Serilog Contributors
1+ // Copyright 2023 Serilog Contributors
22//
33// Licensed under the Apache License, Version 2.0 (the "License");
44// you may not use this file except in compliance with the License.
1212// See the License for the specific language governing permissions and
1313// limitations under the License.
1414
15+ using System ;
1516using Serilog . Events ;
1617using Serilog . Sinks . SystemConsole . Rendering ;
1718
18- namespace Serilog . Sinks . SystemConsole . Output
19- {
20- /// <summary>
21- /// Implements the {Level} element.
22- /// can now have a fixed width applied to it, as well as casing rules.
23- /// Width is set through formats like "u3" (uppercase three chars),
24- /// "w1" (one lowercase char), or "t4" (title case four chars).
25- /// </summary>
26- static class LevelOutputFormat
27- {
28- static readonly string [ ] [ ] TitleCaseLevelMap =
29- {
30- new [ ] { "V" , "Vb" , "Vrb" , "Verb" } ,
31- new [ ] { "D" , "De" , "Dbg" , "Dbug" } ,
32- new [ ] { "I" , "In" , "Inf" , "Info" } ,
33- new [ ] { "W" , "Wn" , "Wrn" , "Warn" } ,
34- new [ ] { "E" , "Er" , "Err" , "Eror" } ,
35- new [ ] { "F" , "Fa" , "Ftl" , "Fatl" } ,
36- } ;
19+ namespace Serilog . Sinks . SystemConsole . Output ;
3720
38- static readonly string [ ] [ ] LowercaseLevelMap =
39- {
40- new [ ] { "v" , "vb" , "vrb" , "verb" } ,
41- new [ ] { "d" , "de" , "dbg" , "dbug" } ,
42- new [ ] { "i" , "in" , "inf" , "info" } ,
43- new [ ] { "w" , "wn" , "wrn" , "warn" } ,
44- new [ ] { "e" , "er" , "err" , "eror" } ,
45- new [ ] { "f" , "fa" , "ftl" , "fatl" } ,
46- } ;
21+ /// <summary>
22+ /// Implements the {Level} element.
23+ /// can now have a fixed width applied to it, as well as casing rules.
24+ /// Width is set through formats like "u3" (uppercase three chars),
25+ /// "w1" (one lowercase char), or "t4" (title case four chars).
26+ /// </summary>
27+ static class LevelOutputFormat
28+ {
29+ static readonly string [ ] [ ] TitleCaseLevelMap = {
30+ new [ ] { "V" , "Vb" , "Vrb" , "Verb" , "Verbo" , "Verbos" , "Verbose" } ,
31+ new [ ] { "D" , "De" , "Dbg" , "Dbug" , "Debug" } ,
32+ new [ ] { "I" , "In" , "Inf" , "Info" , "Infor" , "Inform" , "Informa" , "Informat" , "Informati" , "Informatio" , "Information" } ,
33+ new [ ] { "W" , "Wn" , "Wrn" , "Warn" , "Warni" , "Warnin" , "Warning" } ,
34+ new [ ] { "E" , "Er" , "Err" , "Eror" , "Error" } ,
35+ new [ ] { "F" , "Fa" , "Ftl" , "Fatl" , "Fatal" }
36+ } ;
4737
48- static readonly string [ ] [ ] UppercaseLevelMap =
49- {
50- new [ ] { "V" , "VB" , "VRB" , "VERB" } ,
51- new [ ] { "D" , "DE" , "DBG" , "DBUG" } ,
52- new [ ] { "I" , "IN" , "INF" , "INFO" } ,
53- new [ ] { "W" , "WN" , "WRN" , "WARN" } ,
54- new [ ] { "E" , "ER" , "ERR" , "EROR" } ,
55- new [ ] { "F" , "FA" , "FTL" , "FATL" } ,
56- } ;
38+ static readonly string [ ] [ ] LowerCaseLevelMap = {
39+ new [ ] { "v" , "vb" , "vrb" , "verb" , "verbo" , "verbos" , "verbose" } ,
40+ new [ ] { "d" , "de" , "dbg" , "dbug" , "debug" } ,
41+ new [ ] { "i" , "in" , "inf" , "info" , "infor" , "inform" , "informa" , "informat" , "informati" , "informatio" , "information" } ,
42+ new [ ] { "w" , "wn" , "wrn" , "warn" , "warni" , "warnin" , "warning" } ,
43+ new [ ] { "e" , "er" , "err" , "eror" , "error" } ,
44+ new [ ] { "f" , "fa" , "ftl" , "fatl" , "fatal" }
45+ } ;
5746
58- public static string GetLevelMoniker ( LogEventLevel value , string ? format = null )
59- {
60- if ( format is null || format . Length != 2 && format . Length != 3 )
61- return Casing . Format ( value . ToString ( ) , format ) ;
47+ static readonly string [ ] [ ] UpperCaseLevelMap = {
48+ new [ ] { "V" , "VB" , "VRB" , "VERB" , "VERBO" , "VERBOS" , "VERBOSE" } ,
49+ new [ ] { "D" , "DE" , "DBG" , "DBUG" , "DEBUG" } ,
50+ new [ ] { "I" , "IN" , "INF" , "INFO" , "INFOR" , "INFORM" , "INFORMA" , "INFORMAT" , "INFORMATI" , "INFORMATIO" , "INFORMATION" } ,
51+ new [ ] { "W" , "WN" , "WRN" , "WARN" , "WARNI" , "WARNIN" , "WARNING" } ,
52+ new [ ] { "E" , "ER" , "ERR" , "EROR" , "ERROR" } ,
53+ new [ ] { "F" , "FA" , "FTL" , "FATL" , "FATAL" }
54+ } ;
6255
63- // Using int.Parse() here requires allocating a string to exclude the first character prefix.
64- // Junk like "wxy" will be accepted but produce benign results.
65- var width = format [ 1 ] - '0' ;
66- if ( format . Length == 3 )
67- {
68- width *= 10 ;
69- width += format [ 2 ] - '0' ;
70- }
56+ public static string GetLevelMoniker ( LogEventLevel value , string ? format = null )
57+ {
58+ var index = ( int ) value ;
59+ if ( index is < 0 or > ( int ) LogEventLevel . Fatal )
60+ return Casing . Format ( value . ToString ( ) , format ) ;
7161
72- if ( width < 1 )
73- return string . Empty ;
62+ if ( format == null || format . Length != 2 && format . Length != 3 )
63+ return Casing . Format ( GetLevelMoniker ( TitleCaseLevelMap , index ) , format ) ;
7464
75- if ( width > 4 )
76- {
77- var stringValue = value . ToString ( ) ;
78- if ( stringValue . Length > width )
79- stringValue = stringValue . Substring ( 0 , width ) ;
80- return Casing . Format ( stringValue ) ;
81- }
65+ // Using int.Parse() here requires allocating a string to exclude the first character prefix.
66+ // Junk like "wxy" will be accepted but produce benign results.
67+ var width = format [ 1 ] - '0' ;
68+ if ( format . Length == 3 )
69+ {
70+ width *= 10 ;
71+ width += format [ 2 ] - '0' ;
72+ }
8273
83- var index = ( int ) value ;
84- if ( index >= 0 && index <= ( int ) LogEventLevel . Fatal )
85- {
86- switch ( format [ 0 ] )
87- {
88- case 'w' :
89- return LowercaseLevelMap [ index ] [ width - 1 ] ;
90- case 'u' :
91- return UppercaseLevelMap [ index ] [ width - 1 ] ;
92- case 't' :
93- return TitleCaseLevelMap [ index ] [ width - 1 ] ;
94- }
95- }
74+ if ( width < 1 )
75+ return string . Empty ;
9676
97- return Casing . Format ( value . ToString ( ) , format ) ;
77+ switch ( format [ 0 ] )
78+ {
79+ case 'w' :
80+ return GetLevelMoniker ( LowerCaseLevelMap , index , width ) ;
81+ case 'u' :
82+ return GetLevelMoniker ( UpperCaseLevelMap , index , width ) ;
83+ case 't' :
84+ return GetLevelMoniker ( TitleCaseLevelMap , index , width ) ;
85+ default :
86+ return Casing . Format ( GetLevelMoniker ( TitleCaseLevelMap , index ) , format ) ;
9887 }
9988 }
100- }
89+
90+ static string GetLevelMoniker ( string [ ] [ ] caseLevelMap , int index , int width )
91+ {
92+ var caseLevel = caseLevelMap [ index ] ;
93+ return caseLevel [ Math . Min ( width , caseLevel . Length ) - 1 ] ;
94+ }
95+
96+ static string GetLevelMoniker ( string [ ] [ ] caseLevelMap , int index )
97+ {
98+ var caseLevel = caseLevelMap [ index ] ;
99+ return caseLevel [ caseLevel . Length - 1 ] ;
100+ }
101+ }
0 commit comments