2016-11-04 2 views
1

Я использую log4net в веб-службе, и я хочу установить имя файла журнала для запроса на основе пользовательского параметра, отправленного в самом запросе.Динамически задает имя файла log4net в журнале веб-службы

Я определил свойство в конфигурации

<configuration> 
    <configSections> 
    <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net"/> 
    </configSections> 
    <log4net> 
    <appender name="ClaimLog" type="log4net.Appender.RollingFileAppender"> 
     <file type="log4net.Util.PatternString" value="C:\projects\reports\ClaimRpt\Log\ClaimLog_%property{UserNameWCF}.txt" /> 

и установить его в начале моего веб-метода

type ClaimServiceF() = 


    let log = LogManager.GetLogger("ClaimServiceF") 

...

member this.BeginReport(sel: Model.Selection) : Model.RptResponse = 
    GlobalContext.Properties.Item("UserNameWCF") <- sel.User 
    let rptResp = new Model.RptResponse() 
    log.Info("Started") 
    match sel with 
    | null -> 

Я завершая библиотеку F # (SrvImplF.dll) в проекте C# WCF (why?) и тестируя его с помощью тестового клиента WCF Vis ual Studio.

Но лог-файл протокол остается в своем первоначальном значении ClaimLog_(null).txt, даже если я могу установить точку останова и увидеть, что sel.User правильно заполнен

Я также попытался с провайдером типа AppSettings от AppSettings

<appSettings> 
    <add key="my_service_log" value="C:\projects\reports\ClaimRpt\Log\ClaimLog_{UserNameWCF}.txt" /> 
    </appSettings> 

кодированием

open FSharp.Configuration 
type Settings = AppSettings<"app.config"> 

...

let appender = LogManager.GetRepository().GetAppenders() |> Seq.find(fun x -> x.Name.Equals("ClaimLog")) :?> log4net.Appender.RollingFileAppender 

...

appender.File <- Settings.MyServiceLog.Replace("{UserNameWCF}",sel.User) 

но - кроме того, что мне нужно создать фиктивную app.config под DLL и дублировать ключ приложения там, потому что поставщик типа не видит приложение. конфигурации проекта оберточной - он бросает исключение

исключение брошенную: «System.TypeInitializationException» в SrvImplF.dll исключение типа «System.TypeInitializationException» произошло в SrvImplF.dll но не Handl ed в коде пользователя Дополнительная информация: Инициализатор типа для «FSharp.Configuration.AppSettingsTypeProvider» сделал исключение.

Я думаю, что это последнее является лишь несущественной ошибкой в ​​моей конфигурации поставщика типа, во всяком случае также непосредственно ввода значения

 let configFile = "C:\reports\ClaimRpt\Log\ClaimLog_{UserNameWCF}.txt" //Settings.MyServiceLog 
     appender.File <- configFile.Replace("{UserNameWCF}",sel.User) 

не является исключением, но лог файл остается неизменным ClaimLog_(null).txt

ответ

1

Вы необходимо позвонить LogManager.GetLogger("ClaimServiceF")после, установив собственность.

Обратите внимание, что ваш подход зависит от условий гонки. Если несколько клиентов обращаются к вашему приложению одновременно, вы можете завершить запись в неправильный файл. Предположим, например.следующий порядок выполнения двух параллельных запросов:

// incoming request A 
GlobalContext.Properties.Item("UserNameWCF") <- sel.User 

// incoming request B 
GlobalContext.Properties.Item("UserNameWCF") <- sel.User 

// request A 
var logger = LogManager.GetLogger("ClaimServiceF") 
// logger has 'UserNameWCF' set to 'sel.User' of request B 

Чтобы устранить эту проблему рассмотреть вопрос об использовании ThreadContext, которые «присоединяет» или «прицелы» имущество на запрос, так как каждый запрос обрабатывается отдельно (объединены, повторно) нить. Обратите особое внимание, если вы используете async/await, чтобы установить свойство и получить логгер в том же потоке.

+0

@GoFunctional Есть ли у вас какие-либо дополнительные сведения об исключении, создаваемом TypeProvider? Кроме того, согласно правилам StackOverflow, проблема с типом поставщика должна быть отдельным вопросом. Я рекомендую вам отредактировать свою и создать новую. – CaringDev

+0

@GoFunctional да, точно. ThreadContext смягчает указанную проблему. Что касается сложного контекста: это обеспечивает еще больший/более мелкий контроль над областями свойств. Для вашего случая использования это ненужная сложность, ИМО. – CaringDev