Какой каркас логирования лучше использовать в коде F # - PullRequest
15 голосов
/ 10 марта 2011

Мне нужно добавить запись в мой проект F #. Для кода C # мы использовали: Log4net или NLog (возможно, две из самых популярных платформ журналирования для .Net).

Как лучше всего использовать код F #? Я имею в виду, есть ли какая-либо конкретная структура ведения журнала, написанная для использования в коде F #?

Ответы [ 3 ]

12 голосов
/ 13 сентября 2014

Использовать Logary

https://github.com/logary/logary

Logary поддерживает ведение журнала, метрик и распределенной трассировки для .Net Core.

Цели включают в себя: TextWriter, Console, LiterateConsole, Debugger,GCP Pub / Sub, GCP BigQuery, GCP Stackdriver, Jaeger, TCP (грузоотправитель), UDP (грузоотправитель), ZeroMQ (грузоотправитель) Elasticsearch, графит / статистика, elmah.io, Aliyun, Azure ApplicationInsights, Mixpanel (коммерческий), OpsGenie (коммерческий)), Server-sent-events (веб-рассылка).

Кроме того, вы можете выставить HTTP-сервер для Proemetheus для очистки с помощью Logary.Prometheus.

Он также имеет Dash-сервис, который поддерживает отправку журналов в режиме реального времени в ваш веб-браузер.

Кроме того, Logary Rutta - это реализация контейнера в виде коляски или автономный маршрутизатор журналов для эры нативных облаков.

Logary JS - это библиотека журналов и метрик для JavaScript, которая может быть отправлена ​​в Logary Rutta на стороне сервера, откуда вы можете затем перемещать журналы в любую из доступных целей.

Logary Facade является фасадом с лицензией Apache 2, вы можете копировать-n-paste во все свои библиотеки C # и F # и получать высококачественное ведение журнала консоли.

Журнал записывается на F # для F # в первую очередь.

Install-Package Logary

документы здесь

Все вышеперечисленное можно бесплатно использовать в некоммерческих целях.Вы можете увидеть различные лицензии здесь.

12 голосов
/ 10 марта 2011

Насколько я знаю, они одинаковы для F #, то есть в них нет ничего специфичного для F # (хорошо это или плохо).Помимо конфигурации, использование в значительной степени одинаково для всех библиотек журналов.

Что вы можете добавить, это журналирование с включенной печатью, поэтому вместо logger.DebugFormat("Hello {0}", "world") или logger.Debug(sprintf "Hello %s" "world") вы можете просто сделать logger.Debugf "Hello %s" "world",Для этого используйте расширения типа и kprintf .

1 голос
/ 10 января 2019

Я сделал что-то вроде этого (используя словесный синтаксис):

#light "off"
open System.Runtime.CompilerServices

let inline (|?) (a: 'a option) b = if a.IsSome      then a.Value else b; // coalesce operator
  type T() = class
        static member private printLog(par) =
           match ( par) with
                | msg, Some m, Some p, Some l  -> (
                    let pl = Array.head  (Array.rev( string(p).Split([|'\\';'/'|]))) in
                    printfn "at %s(%s: line %d) %s" m pl l msg
                    )
                | msg, _,_,_ -> printfn "at ?? %s" msg
        static member LOG(msg: string, ?a:obj,
                          [<CallerMemberName>] ?memberName: string,
                          [<CallerFilePath>] ?path: string,
                          [<CallerLineNumber>] ?line: int) = match a with
                    | Some a -> (match a with
                          | :? int as i -> T.printLog((sprintf "%s %d" msg i), memberName, path,line)
                          | :? float as f -> T.printLog((sprintf "%s %f" msg f), memberName, path,line)
                          | _ -> T.printLog((sprintf "%s %A" msg a), memberName, path,line)
                                    )
                    | None -> T.printLog(msg, memberName, path,line)
          static member EXIT(?msg:string, [<CallerMemberName>] ?memberName: string,
                          [<CallerFilePath>] ?path: string,
                          [<CallerLineNumber>] ?line: int) =
                  printf "Exiting ... ";
                  T.printLog((msg |? "Giving up!"), memberName, path,line);
                  exit 1
   end

использование:

"text pushed in" |> T.LOG;
T.LOG "just text at line ";
T.LOG ("just text at line in par");
T.LOG ("string ", "text i got");
T.LOG ("int ", 1);
T.LOG ("tuple ", (1,2));
let  msg  = Some "existing optional value" in 
printfn """ (msg |? "this is default value\")  --->  %A""" (msg |? "d
T.EXIT( "after all test done no TODO new extentions");

производит:

at testit(TautoLogics.fs: line 49) text pushed in
at testit(TautoLogics.fs: line 52) just text at line
at testit(TautoLogics.fs: line 53) just text at line in par
at testit(TautoLogics.fs: line 54) string  "text i got"
at testit(TautoLogics.fs: line 55) int  1
at testit(TautoLogics.fs: line 56) tuple  (1, 2)
'(msg |? "this is default value\")  --->  "existing optional value"
Exiting ... at testit(TautoLogics.fs: line 63) after all test done

просто и легко использовать для меня.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...