CXuesong / WikiClientLibrary

/*🌻*/ Wiki Client Library is an asynchronous MediaWiki API client library targeting modern .NET platforms
https://github.com/CXuesong/WikiClientLibrary/wiki
Apache License 2.0
80 stars 16 forks source link

Use an existing logging framework for the activity logs #14

Closed CXuesong closed 6 years ago

CXuesong commented 7 years ago

As mentioned in #13, the current WikiClientLibrary.ILogger is just error-prone for the library-side code, and the class name is very likely to conflict with other logging libraries. May consider Microsoft.Extensions.Logging.Abstractions, though Serilog might also be a good choice.

A good point might be that if you pass a ILoggerFactory into WikiClient, this factory can be used automatically (or not, configured by user)[1] in other related classes, e.g., WikiSites and WikiClients.

[1] The user can manually remove the logger after the related class instance is created.

CXuesong commented 7 years ago

WikiClientLibrary.ILogger will be removed, and a new interface such as IWikiClientLoggable will be introduced, like this

interface IWikiClientLoggable
{
    void SetLoggerFactory(ILoggerFactory factory);
}
CXuesong commented 6 years ago

For a better clarity, I will take use of the "scope" feature MEL provides. The new IWikiClientLoggable would be like this

interface IWikiClientLoggable
{
    ILogger Logger { get; set; }
}

To begin with, I am worried about the multi-threading behavior of scopes, but later I took a look at MS's implementation of ILogger,[1] which uses AsyncLocal<T> to keep track of the current scope.[2] Perhaps I can count on this.

Under the new design, client only needs to pass ILogger instances to WikiClient and WikiSite, respectively and WikiSite can implicitly use WikiClient's logger on initialization. Other classes, such as WikiPage, will just use WikiSite's logger, but in a different scope.

CXuesong commented 6 years ago

With the new scoped logging, the emitted log looks like

Trace: WikiClientLibrary.Client.WikiClient
        -> WikiClient#17363659 -> ::InvokeAsync(452849D100000001)
       Initiate request to: https://test2.wikipedia.org/w/api.php.
Trace: WikiClientLibrary.Client.WikiClient
        -> WikiClient#17363659 -> ::InvokeAsync(452849D100000002)
       Initiate request to: https://test2.wikipedia.org/w/api.php.
Trace: WikiClientLibrary.Client.WikiClient
        -> WikiClient#17363659 -> ::InvokeAsync(452849D100000002)
       HTTP 200, elapsed: 00:00:01.5715946
Trace: WikiClientLibrary.Client.WikiClient
        -> WikiClient#17363659 -> ::InvokeAsync(452849D100000001)
       HTTP 200, elapsed: 00:00:01.8922563
Debug: WikiClientLibrary.Sites.WikiSite
        -> Wikipedia -> ::LoginAsync(XuesongBot) -> Wikipedia -> ::FetchTokenAsyncCore(login)
       Sending request 452849D100000003, SuppressAccountAssertion=True
Trace: WikiClientLibrary.Client.WikiClient
        -> Wikipedia -> ::LoginAsync(XuesongBot) -> Wikipedia -> ::FetchTokenAsyncCore(login) -> WikiClient#17363659 -> ::InvokeAsync(452849D100000003)
       Initiate request to: https://test2.wikipedia.org/w/api.php.
Trace: WikiClientLibrary.Client.WikiClient
        -> Wikipedia -> ::LoginAsync(XuesongBot) -> Wikipedia -> ::FetchTokenAsyncCore(login) -> WikiClient#17363659 -> ::InvokeAsync(452849D100000003)
       HTTP 200, elapsed: 00:00:00.3799395
Debug: WikiClientLibrary.Sites.WikiSite
        -> Wikipedia -> ::LoginAsync(XuesongBot)
       Sending request 452849D100000004, SuppressAccountAssertion=True
Trace: WikiClientLibrary.Client.WikiClient
        -> Wikipedia -> ::LoginAsync(XuesongBot) -> WikiClient#17363659 -> ::InvokeAsync(452849D100000004)
       Initiate request to: https://test2.wikipedia.org/w/api.php.
Trace: WikiClientLibrary.Client.WikiClient
        -> Wikipedia -> ::LoginAsync(XuesongBot) -> WikiClient#17363659 -> ::InvokeAsync(452849D100000004)
       HTTP 200, elapsed: 00:00:01.3669340
Warning: WikiClientLibrary.Client.WikiClient
          -> Wikipedia -> ::LoginAsync(XuesongBot) -> WikiClient#17363659 -> ::InvokeAsync(452849D100000004)
         API warning [main]: "*": "Subscribe to the mediawiki-api-announce mailing list at <https://lists.wikimedia.org/mailman/listinfo/mediawiki-api-announce> for notice of API deprecations and breaking changes. Use [[Special:ApiFeatureUsage]] to see usage of deprecated features by your application."
Warning: WikiClientLibrary.Client.WikiClient
          -> Wikipedia -> ::LoginAsync(XuesongBot) -> WikiClient#17363659 -> ::InvokeAsync(452849D100000004)
         API warning [login]: "*": "Main-account login via \"action=login\" is deprecated and may stop working without warning. To continue login with \"action=login\", see [[Special:BotPasswords]]. To safely continue using main-account login, see \"action=clientlogin\"."
Debug: WikiClientLibrary.Sites.WikiSite
        -> Wikipedia -> ::LoginAsync(XuesongBot) -> Wikipedia -> ::RefreshAccountInfoAsync()
       Sending request 452849D100000005, SuppressAccountAssertion=True
Trace: WikiClientLibrary.Client.WikiClient
        -> Wikipedia -> ::LoginAsync(XuesongBot) -> Wikipedia -> ::RefreshAccountInfoAsync() -> WikiClient#17363659 -> ::InvokeAsync(452849D100000005)
       Initiate request to: https://test2.wikipedia.org/w/api.php.
Trace: WikiClientLibrary.Client.WikiClient
        -> Wikipedia -> ::LoginAsync(XuesongBot) -> Wikipedia -> ::RefreshAccountInfoAsync() -> WikiClient#17363659 -> ::InvokeAsync(452849D100000005)
       HTTP 200, elapsed: 00:00:00.3718677
Information: WikiClientLibrary.Sites.WikiSite
              -> Wikipedia -> ::LoginAsync(XuesongBot)
             Logged in as XuesongBot.
Debug: WikiClientLibrary.Sites.WikiSite
        -> Wikipedia -> [WikiPage{Wikipedia:Sandbox}]::RefreshPagesAsync(FetchContent)
       Fetching 1 pages.
Debug: WikiClientLibrary.Sites.WikiSite
        -> Wikipedia -> [WikiPage{Wikipedia:Sandbox}]::RefreshPagesAsync(FetchContent)
       Sending request 452849D100000006, SuppressAccountAssertion=False
Trace: WikiClientLibrary.Client.WikiClient
        -> Wikipedia -> [WikiPage{Wikipedia:Sandbox}]::RefreshPagesAsync(FetchContent) -> WikiClient#17363659 -> ::InvokeAsync(452849D100000006)
       Initiate request to: https://test2.wikipedia.org/w/api.php.
Trace: WikiClientLibrary.Client.WikiClient
        -> Wikipedia -> [WikiPage{Wikipedia:Sandbox}]::RefreshPagesAsync(FetchContent) -> WikiClient#17363659 -> ::InvokeAsync(452849D100000006)
       HTTP 200, elapsed: 00:00:00.4243953

Debug: WikiClientLibrary.Sites.WikiSite
        -> Wikipedia -> WikiPage{Wikipedia:Sandbox}::UpdateContentAsync()
       Edit: Wikipedia:Sandbox#51235807: Waiting for delay 00:00:05.
Debug: WikiClientLibrary.Sites.WikiSite
        -> Wikipedia -> WikiPage{Wikipedia:Sandbox}::UpdateContentAsync() -> Wikipedia -> ::FetchTokenAsyncCore(csrf)
       Sending request 452849D100000008, SuppressAccountAssertion=True
Trace: WikiClientLibrary.Client.WikiClient
        -> Wikipedia -> WikiPage{Wikipedia:Sandbox}::UpdateContentAsync() -> Wikipedia -> ::FetchTokenAsyncCore(csrf) -> WikiClient#17363659 -> ::InvokeAsync(452849D100000008)
       Initiate request to: https://test2.wikipedia.org/w/api.php.
Trace: WikiClientLibrary.Client.WikiClient
        -> Wikipedia -> WikiPage{Wikipedia:Sandbox}::UpdateContentAsync() -> Wikipedia -> ::FetchTokenAsyncCore(csrf) -> WikiClient#17363659 -> ::InvokeAsync(452849D100000008)
       HTTP 200, elapsed: 00:00:00.3663925
Debug: WikiClientLibrary.Sites.WikiSite
        -> Wikipedia -> WikiPage{Wikipedia:Sandbox}::UpdateContentAsync()
       Sending request 452849D100000007, SuppressAccountAssertion=False
Trace: WikiClientLibrary.Client.WikiClient
        -> Wikipedia -> WikiPage{Wikipedia:Sandbox}::UpdateContentAsync() -> WikiClient#17363659 -> ::InvokeAsync(452849D100000007)
       Initiate request to: https://test2.wikipedia.org/w/api.php.
Trace: WikiClientLibrary.Client.WikiClient
        -> Wikipedia -> WikiPage{Wikipedia:Sandbox}::UpdateContentAsync() -> WikiClient#17363659 -> ::InvokeAsync(452849D100000007)
       HTTP 200, elapsed: 00:00:00.5573600
Information: WikiClientLibrary.Sites.WikiSite
              -> Wikipedia -> WikiPage{Wikipedia:Sandbox}::UpdateContentAsync()
             Edited page. New revid=329827.
Debug: WikiClientLibrary.Sites.WikiSite
        -> Wikipedia -> ::LogoutAsync()
       Sending request 452849D100000009, SuppressAccountAssertion=True
Trace: WikiClientLibrary.Client.WikiClient
        -> Wikipedia -> ::LogoutAsync() -> WikiClient#17363659 -> ::InvokeAsync(452849D100000009)
       Initiate request to: https://test2.wikipedia.org/w/api.php.
Trace: WikiClientLibrary.Client.WikiClient
        -> Wikipedia -> ::LogoutAsync() -> WikiClient#17363659 -> ::InvokeAsync(452849D100000009)
       HTTP 200, elapsed: 00:00:00.4894650
Debug: WikiClientLibrary.Sites.WikiSite
        -> Wikipedia -> ::LogoutAsync() -> Wikipedia -> ::RefreshAccountInfoAsync()
       Sending request 452849D10000000A, SuppressAccountAssertion=True
Trace: WikiClientLibrary.Client.WikiClient
        -> Wikipedia -> ::LogoutAsync() -> Wikipedia -> ::RefreshAccountInfoAsync() -> WikiClient#17363659 -> ::InvokeAsync(452849D10000000A)
       Initiate request to: https://test2.wikipedia.org/w/api.php.
Trace: WikiClientLibrary.Client.WikiClient
        -> Wikipedia -> ::LogoutAsync() -> Wikipedia -> ::RefreshAccountInfoAsync() -> WikiClient#17363659 -> ::InvokeAsync(452849D10000000A)
       HTTP 200, elapsed: 00:00:00.3658774