Как стать автором
Обновить
0
0

Пользователь

Отправить сообщение
А что мешает в production написать что-то вроде такого:

<nlog>
 <rules>
  <!-- Логируем события любого уровня от ValuesController -->
  <logger name="ValuesController" writeTo="traceFile" minlevel="Trace" />
  <!-- Детальные логи по ошибкам -->
  <logger name="*" writeTo="email,errorFile" minlevel="Warn" />
  <!-- Общие логи по работе системы -->
  <logger name="*" writeTo="commonFile" minlevel="Info" />
 </rules>
</nlog>


Для более сложных критериев можно воспользоваться фильтрами.

Отмечу, что nlog не поддерживает декларативную конфигурацию в appsettings.json, только XML. Если все же хочется работать с конфигами в json, то рекомендую Serilog. Но суть будет примерно та же…
Вы не правильно понимаете, что такое уровни логирования. Так Logger.Trace() и Logger.Debug() пишут информацию для разработчиков; Logger.Info() — разовые операции, которые влияют на поведение системы (например: обновление конфига или загрузка плагина); Logger. Warning() – сигнализирует о потенциальных проблемах; Logger. Error () и Logger. Fatal() – детали ошибки.

Обычно, в DEV-конфигурации для записи логов используется минимальный уровень события Trace, а для PROD – минимальным уровнем выставляется Info.

Я бы переформулировал вашу задачу с «Должен существовать способ установить отдельный уровень логирования для каждого запроса.» на «Требуется логировать событий по переделённым критериям (в том числе, параметрам запроса)».

Я не работал с log4net, но, например, в NLog или Serilog эти критерии и таргеты вывода можно декларативно прописать в конфигурационном файле.

Для .Net Core, если логгер используется под оберткой ILogger из Microsoft.Extensions.Logging, то контекст логгера для можно создать методом Logger.BeginScope(…). В частности, реализовав middleware, в котором вызывается Logger.BeginScope(…) можно добавить нестандартные параметры во все события запроса и потом делать по ним фильтрацию.
Если нет разницы...

Странно, но по мне разница есть. И она описывает соглашение того, что мы ожидаем получить в thing.


Использую оба варинта:


  • вариант 1 — если в thing может быть произвольного типа.
  • вариант 2 — если в thing обязан реализовать контракт типа Foo

И да, проверка на null — для обоих результатов обязательна, с выбрасыванием "вменяемого" исключения.

Вопрос: Совместимы ли системы синхронизации Vivaldi и Chrome?
Ответ: Нет, наша версия синхронизации не будет работать с синхронизацией Chrome.

Вот только поэтому и не планирую использовать Vivaldi. Сhrome — мой рабочий инструмент. Ну вот почему для смены браузера мне приходиться предать родину, сменить религию отказываться от привычного окружения.


Когда-то эту проблему успешно решал плагин Xmarks, но сегодня хотелось бы иметь аналогичный штатный механизм в браузере.


Такая же история с Yandex.Браузер — по моему впечатлению клиент на Android удобнее Chrome. Но я не готов ради браузера отказываться от всего остального.

Методы для интерфейсов и сейчас без проблем добавляются через extensions-методы:


public interface IRectangle
{
    int Width { get; }
    int Height { get; }
}

public static class IRectangleExtensions
{
    public static int GetArea(this IRectangle r) => r.Width * r.Height;
}

Как по мне, так вполне вменяемое применение. Просто упростят реализацию.
И будет логично, что переопределить метод интерфейса будет невозможно.

Ну, в общем случае настройка окружения не ограничивается только appSettings. Как минимум, еще будет system.net\mailSettings, connectionStrings, system.web\customErrors, содержимое system.serviceModel, настройки логов (nlog и/или system.diagnostic). Так что держать все это в одном файле, как мне кажется, проще.


Offtop

Если честно, то приведенный выше пример я давно не использую. Сейчас предпочитаю хранить в appSettings один параметр DeployMode, на основе которого производится конфигурация IoC-контейнера. Получается более гибко, плюс строгая типизация не даст что-нибудь забыть.

Я решал эту задачу используя штатный Web.config Transformation:


1) Добавляем /Web.config в .gitignore


2) Создаем конфигурации для требуемых вариантов сборки:


  • /App_Config/Web.config
  • /App_Config/Web.Release.config
  • /App_Config/Web.Stage.config

3) Добавляем небольшой код в файл проекта:


  <PropertyGroup>
    <SiteConfigDir>$(MSBuildProjectDirectory)\App_Config</SiteConfigDir>
    <SiteRootDir>$(MSBuildProjectDirectory)</SiteRootDir>
  </PropertyGroup>
  <Target Name="ProcessConfigFiles">
    <TransformXml Condition="Exists('$(SiteConfigDir)\Web.$(Configuration).config')" Source="$(SiteConfigDir)\Web.config" Transform="$(SiteConfigDir)\Web.$(Configuration).config" Destination="$(SiteRootDir)\Web.config" StackTrace="true" />
    <Copy Condition="!Exists('$(SiteConfigDir)\Web.$(Configuration).config')" SourceFiles="$(SiteConfigDir)\Web.config" DestinationFolder="$(SiteRootDir)" OverwriteReadOnlyFiles="true" />
  </Target>
  <Target Name="AfterBuild">
    <CallTarget Targets="ProcessConfigFiles" />
  </Target>

Pros:


  • \Web.config не попадает в pending changes
  • все варианты настроек хранятся в git.

Cons:


  • нужно не забывать, что правки требуется вносить в /App_Config/Web.config, а не в /Web.config.
  • после изменения конфигурации нужно пересобрать проект
"… Предположим, что мы для каждого рецепта хотим предоставить клиенту набор рекомендаций … "

Мне кажется, что обычно клиент решает свою задачу, и стороннее API подключается по принципу «подключил и забыл…». Странно ожидать от него, что он будет следить за рекомендациями.

Информация

В рейтинге
Не участвует
Зарегистрирован
Активность