Я думаю, что сейчас происходит то, что ваши «события журнала» должным образом обогащены всей информацией, но приемник File
неправильно настроен для отображения этой информации.
Шаблон вывода по умолчанию приемника File
- {Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} \[{Level:u3}\] {Message:lj}{NewLine}{Exception}
, что означает, что он будет правильно отображать «обработанное сообщение» (шаблон сообщения + значение свойства, на которые есть ссылки в шаблоне сообщения).
Что вам нужно сделать, это настроить его так, чтобы все дополнительные свойства (те, которые добавляются к каждому событию журнала при его обогащении) также отображались.
Для приемника File
вы можете, например, добавить специальную директиву {Properties}
в шаблон вывода, который будет показывать все свойства, которые прикреплены к событию, но не отображаются. как часть шаблона сообщения.
Это выглядело бы так:
Log.Logger = new LoggerConfiguration()
.Enrich.WithWebApiActionName()
.WriteTo.File("D:/mytestresults.txt", outputTemplate: "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} \[{Level:u3}\] {Message:lj}{Properties}{NewLine}{Exception}")
.CreateLogger();
(или {Properties:j}
, чтобы они были отформатированы как JSON).
Это выведет все свойства, прикрепленные к событию, но не расположенные где-либо еще в шаблоне вывода.
Если вас интересует только WebApiAction
, вы также можете сделать что-то вроде:
Log.Logger = new LoggerConfiguration()
.Enrich.WithWebApiActionName()
.WriteTo.File("D:/mytestresults.txt", outputTemplate: "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} \[{Level:u3}\]<{WebApiAction}> {Message:lj}{NewLine}{Exception}")
.CreateLogger();
... и тогда вы получите такие строки в выводе:
2019-03-26 10:09:13.621 -04:00 [INF] HTTP GET /api/actions/ responded 200 in 9ms
ОБНОВЛЕНИЕ
Похоже, что это не проблема «форматирования вывода», поскольку вы можете правильно отобразить некоторые вложенных свойства. ..
.WithUserName
и .WithRequestUrl
не являются специфичными для WebApi и могут быть легко собраны для любого приложения ASP.NET. Расширения .WithWebApi*
опираются на IAuthenticationFilter
, который мы объявляем в Web API при запуске благодаря этой строке ...
] Вот возможные сценарии, которые могут объяснить отсутствие обогащения: - по какой-то причине атрибут сборки PreApplicationStartMethod
не работает должным образом - по какой-то причине регистрация StoreWebApInfoInHttpContextAuthenticationFilter
в Web API не работает - по какой-то причине мы не можем извлечь информация из ActionContext
Возможно, вы делаете «странные» вещи с зарегистрированными AuthenticationFilter
при запуске?
Вероятно, лучше попытаться отследить это как часть проблемы, о которой вы сообщили здесь: https://github.com/serilog-web/classic-webapi/issues/18 ; )
Почему @p3 и @p4 имеют 2x одинарные кавычки? Копия и ошибка вставки?
Я не могу проверить (не устанавливайте SQL здесь), но если разделитель миллисекунды не быть "точкой", то есть, "14.03.2009 14:29:37.000"
@p3 "прежде", @p4 "после" здесь:
exec sp_executesql
N'INSERT INTO CustomPages (Title, Term, Content, LastUpdated, DateAdded, StoreID, LastUpdatedById, AddedById, ID)
VALUES (@p0, @p1, @p2, @p3, @p4, @p5, @p6, @p7, @p8)',
N'@p0 nvarchar(21),@p1 nvarchar(21),@p2 nvarchar(33),@p3 datetime,@p4 datetime,@p5 uniqueidentifier,@p6 uniqueidentifier,@p7 uniqueidentifier,@p8 uniqueidentifier',
@p0=N'Size and Colour Chart',
@p1=N'size-and-colour-chart',
@p2=N'This is the size and colour chart',
@p3=''2009-03-14 14:29:37:000'', --quotes + dot wrong?
@p4='2009-03-14 14:29:37.000', --quotes + dot correct?
@p5='48315F9F-0E00-4654-A2C0-62FB466E529D',
@p6='1480221A-605A-4D72-B0E5-E1FE72C5D43C',
@p7='1480221A-605A-4D72-B0E5-E1FE72C5D43C',
@p8='1E421F9E-9A00-49CF-9180-DCD22FCE7F55'
Сценарий SQL в Вашем вопросе выполнился очень хорошо на моей установке SQL 2005 (после того как я устранил проблемы кавычки, взятые gbn). И Ваше отображение также выглядит хорошо. Извините, что был такой небольшой справки.
Я использовал s # Architecture / fluentnhibernate для создания этого отображения, я обновился до последней версии и, похоже, работать нормально.
На самом деле причина, лежащая в основе сцены:
Когда NHibernate читает строку из базы данных, значение равно нулю, и это то, что запоминает сеанс. Когда объект повторно гидратируется NHibernate, Date устанавливается в значение DateTime.MinValue. Когда сеанс синхронизируется с базой данных, NHibernate предполагает, что что-то изменилось, потому что currentState и previousState разные, и пытается обновить строку. Что, в свою очередь, не удается, потому что DateTime.MinValue не помещается в столбец datetime SqlServer.
Решение: сделайте дату и время нулевой, поставив? в конце Datetime, например DateTime? или Nullable
Complete article, можно найти по адресу: nhibernate-sqldatetime-overflow-issue
К вашему сведению, я работал над переносом существующего приложения на NHibernate из различных встроенных подходов к доступу к данным. Эта проблема возникла быстро, и я нашел простое решение, которое минимизировало влияние на существующий функциональный код приложения. Поскольку в некоторых случаях мы выполняем миграцию послойно, интерфейс класса данных должен был оставаться стабильным, если это вообще возможно. Решением здесь было продолжить использование типов DateTime для общедоступного интерфейса, добавить методы расширения к типам закрытых полей для преобразования из MinValue в null и обратно в закрытые поля в средствах доступа и сопоставить nHibernate с закрытыми полями.
JF