Git Product home page Git Product logo

prism.plugin.logging's Introduction

Prism Logging Plugin's

Prism's ILoggerFacade provides logging of all internal Prism errors, and a quick and easy way for your WPF, UWP, or Xamarin Forms app to introduce logging throughout your ViewModels and Services. The implementation of ILoggerFacade is really left to the developer to determine how you want to handle your logging. While this "Works", it is also a more than a decade old definition that doesn't match modern application logging demands. For this reason the Prism Logging Plugins introduce some new logging interfaces:

  • IAnalyticsService
    • adds void TrackEvent(string name, IDictionary<string, string> properties)
  • ICrashesService
    • adds void Report(Exception ex, IDictionary<string, string> properties)
  • ILogger (inherits from IAnalyticsService, ICrashesService, ILoggerFacade)
    • adds void Log(string message, IDictionary<string, string> properties)
    • has extensions for Debug, Info, Warn

Build Status

NuGet

Package NuGet Sponsor Connect
Prism.Plugin.Logging.Abstractions AbstractionsLoggingShield AbstractionsLoggingSponsorConnectShield
Prism.Plugin.Logging.Common CommonLoggingShield CommonLoggingSponsorConnectShield
Prism.Plugin.Logging.AppCenter AppCenterLoggingShield AppCenterLoggingSponsorConnectShield
Prism.Plugin.Logging.AppInsights AppInightsLoggingShield AppInightsLoggingSponsorConnectShield
Prism.Plugin.Logging.Graylog GraylogLoggingShield GraylogLoggingSponsorConnectShield
Prism.Plugin.Logging.Loggly LogglyLoggingShield LogglyLoggingSponsorConnectShield
Prism.Plugin.Logging.Syslog SyslogLoggingShield SyslogLoggingSponsorConnectShield

Support

If this project helped you reduce time to develop and made your app better, please be sure to Star the project help support Dan.

GitHub Sponsors

Providers

Logging is an important facet of app development. It can help you identify how users are navigating through your application, alert you when unexcepted exceptions are thrown, and help shorten the Dev-Loop. Note that the sample below show registering the logger with Prism IContainerRegistry as a Transient Service. It is typically advisable to access the underlying container and register a single instance of your logger against any interfaces that may be called by your app.

// For DryIoc it might look something like this:
var container = containerRegistry.GetContainer();
container.RegisterMany<SyslogLogger>(Reuse.Singleton,
                                     ifAlreadyRegistered: IfAlreadyRegistered.Replace,
                                     serviceTypeCondition: t => typeof(SyslogLogger).ImplementsServiceType(t));

// For Unity it might look something like this:
var logger = Container.Resolve<SyslogLogger>();
containerRegistry.RegisterInstance<ILoggerFacade>(logger);
containerRegistry.RegisterInstance<ILogger>(logger);
containerRegistry.RegisterInstance<IAnalyticsService>(logger);
containerRegistry.RegisterInstance<ICrashesService>(logger);
containerRegistry.RegisterInstance<ISyslogLogger>(logger);

If you're using the Prism.Container.Extensions you might simply register your logger like:

containerRegistry.RegisterManySingleton<SyslogLogger>();

Aggregate Logger

There are times where you may actually want to have multiple logging providers. For instance you may wish to send logs to App Center and the device console at the same time. The Aggregate Logger by default will log to the console, but gives you the ability to explicitly define any loggers that you may wish to use. Note that when you add the first logger it will clear the default Console Logger and you will need to pass in a Console Logger if you wish to continue using the Console Logger as one of the Aggregate Loggers.

protected override void RegisterTypes(IContainerRegistry containerRegistry)
{
    containerRegistry.Register<ISyslogOptions, MySyslogOptions>();
    containerRegistry.RegisterManySingleton<AggregateLogger>();
}

protected override void OnInitialized()
{
    var aggLogger = Container.Resolve<IAggregateLogger>();
    aggLogger.AddLoggers(
        Container.Resolve<ConsoleLoggingService>(),
        Container.Resolve<SyslogLogger>()
    );
}

App Center & Application Insights

The App Center and Application Insights packages both make some assumptions that while running a Debug build that the logging output should be sent to the Application Output (the console in the IDE). Simply running a Release build will trigger the logger to attempt to send telemetry using the App Center or Application Insights SDK's

Starting with version 1.2, two new interfaces were added for mocking Analytics and Crashes. While the Report API was previously available in the ILogger, this has been moved to the ICrashesService, with a new IAnalyticsService that exposes a TrackEvent API. Both of these interfaces are implemented through the ILogger. These services map directly App Center Analytics and Crashes API's. This allows you to null logging events you may use during development, while leaving intact specific tracking of events and crashes.

Using Application Insights

Application Insights requires that you have an Instrumentation Key to create the client. In addition you may pass any root telemetry you wish about your users. This could include the Device type, OS version, etc. You are able to pass both the Instrumentation Key and User Traits to the Application Insights Logger using the IApplicationInsightsOptions. Note that Prism.Forms developers may want implement this on a Platform Specific basis and register this with the IPlatformInitializer.

Debug Logging

Both the App Center and Application Insights loggers attempt to make a determination if the build is a Debug build. This is done based on the entry assembly. All Debug builds will automatically write to the Device Console. The Console will also be used if the underlying service is not available. This could occur becuase you failed to start App Center Crashes or Analyics, or provided the wrong client id for either App Center or Application Insights.

SocketLogger

The SocketLogger is configurable to send messages using any Socket Type you choose. Typically you would choose Udp or Tcp. This works great for simple solutions where you simply want to receive logging messages over the network.

public class SocketOptions : ISocketLoggerOptions
{
    // e.g. 192.168.0.100
    // e.g. logging.contoso.com
    public string HostOrIp => Secrets.LoggingHost;

    public int Port => 12345;

    public ProtocolType ProtocolType => ProtocolType.Udp;
}

public class App : PrismApplication
{
    protected override void RegisterTypes(IContainerRegistry containerRegistry)
    {
        containerRegistry.Register<ISocketLoggerOptions, SocketOptions>();

        // Resolve the logger as a Transient Service
        containerRegistry.Register<ILoggerFacade, SocketLogger>();
        containerRegistry.Register<ILogger, SocketLogger>();
    }
}

Syslog

The Syslog package will enable you to send your logging messages to the Syslog Server of your choice, and works great with Visual Syslog Server.

public class AwesomeAppOptions : ISyslogOptions
{
    // e.g. 192.168.0.100
    // e.g. logging.contoso.com
    public string HostNameOrIp => Secrets.LoggingHost;

    // If this is null, the SyslogLogger will use port 514
    public int? Port => int.Parse(Secrets.LoggingPort);

    public string AppNameOrTag => "AwesomeApp"
}

public class App : PrismApplication
{
    protected override void RegisterTypes(IContainerRegistry containerRegistry)
    {
        containerRegistry.Register<ISyslogOptions, AwesomeAppOptions>();

        // Registers the Syslog Logger as a Transient Service
        containerRegistry.Register<ILoggerFacade, SyslogLogger>();
        containerRegistry.Register<ILogger, SyslogLogger>();
    }
}

Loggly

Loggly offers both free and paid Logging as a Service plans. The Loggly package will allow you to choose from either their Syslog implementation or Rest service.

NOTE By default we will send all requests to logs-01.loggly.com. To override this you will need to inherit from the Logging class.

  • For LogglyHttpLogger you will need to override LogglyBaseUri's default value of https://logs-01.loggly.com
  • For LogglySyslogLogger you will need to implement a Logger class that derives from LogglySyslogLogger and update the HostNameOrIp property.
public class LogglyOptions : ILogglyOptions
{
    public string Token => Secrets.LogglyToken;

    public string AppName => "AwesomeApp";

    public IEnumerable<string> Tags => new string[]
    {
        "sample"
    };
}

public class App : PrismApplication
{
    protected override void RegisterTypes(IContainerRegistry containerRegistry)
    {
        // Used by both the LogglyHttpLogger and LogglySyslogLogger
        containerRegistry.Register<ILogglyOptions, LogglyOptions>();

        containerRegistry.Register<ILoggerFacade, LogglyHttpLogger>();
        // Or
        containerRegistry.Register<ILoggerFacade, LogglySyslogLogger>();
    }
}

Graylog (Graylog Extended Log Format)

Graylog is a very popular Logging platform which will accept Syslog messages. In addition to the Syslog Messages, you can also choose to use the Graylog package to take advantage of the Graylog REST Api and GELF Log Messages.

public class GelfOptions : IGelfOptions
{
    // e.g. http://graylog.example.org:12202
    public Uri Host => new Uri(Secrets.GraylogHost);
}

public class App : PrismApplication
{
    protected override void RegisterTypes(IContainerRegistry containerRegistry)
    {
        containerRegistry.Register<IGelfOptions, GelfOptions>();
        containerRegistry.Register<ILoggerFacade, GelfLogger>();
    }
}

prism.plugin.logging's People

Contributors

alex-munteanu avatar dansiegel avatar dependabot-preview[bot] avatar dependabot[bot] avatar derekfoulk avatar github-actions[bot] avatar logeshpalani30 avatar mdartu avatar radoslawkubas avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

prism.plugin.logging's Issues

Assembly.GetEntryAssembly returns null on Android

Android applications do not contain an actual executable, only libraries. As a result, when calling Assembly.GetEntryAssembly() on Android a null is returned generating a NullReferenceException when attempting to determine if the executing application is running a Debug build or Release. This affects both App Center and Application Insights loggers as they log to the Console on Debug builds.

Add abstractions around Analytics/Crashes

Description

Abstractions should be added for Analytics/Crashes. While ILogger currently has a Report method, this could be pulled into an ICrashesService so that if a developer specifically wants to report crashes they could inject this specific service. Similarly this will help for times where a developer may want to use App Center for Tracking Events and Reporting Exceptions/Crashes, but may still want to run debug logging through a service like Syslog/Graylog/Loggly.

Loggly Tags should be more dynamic

Description

It is easier to filter logs to create a Dashboard in Loggly based on Tags than on properties contained within the Logged body...

General Logs that may come from ILoggerFacade should be discoverable via the category...
Analytics Events should contain a Category TrackedEvent by default
Error Reports should contain a Category Report by default

All defaults should be overrideable by simply including a Category property. Because the Category will be exposed via tag this should be removed from the message body.

Logs not appear in Loggly

First of all all thank you for great job with Prism!

I'm trying to use Logging plugin to send logs to Loggly free account, everything seems to works fine, no errors, except that logs not appear in my loggly account. I make tests with sample/LoggingDemo and same result. I can send logs to syslog server without any problem, but not to Loggly.

It seems to be everything ok with account and setup I'm using, at lease when I try to send logs to my longgly from mac console, it works fine, logs appear, but not with plugin.

Do you have any idea, what may be wrong with my setup, or where to look for reason?

Thank you in advance for any help!

Move ILogger to abstraction project

Description

Certain implementations of the Logging Plugin such as App Center and App Insights only really need the common ILogger interface, and not all of the bloat of the common library. This should be migrated so to an Abstractions project. This will allow a minimal install for code sharing without the network intelligence of the common library. That common library should also probably be renamed

Network Resiliency - Caching

All of the Logging Implementations should be network resilient

  • Store logs locally if there is no network connection
  • Include a mechanism to send all unsent logs
  • Include a mechanism to send oldest log information first before trying new log.

AppCenterLogger constructor fails

"Exception occurred while: Calling constructor Prism.Logging.AppCenter.AppCenterLogger().
Exception is: NullReferenceException - Object reference not set to an instance of an object."

Cannot initialize instance of AppCenterLogger.

Version 1.1.0.85.

Integrate loggers (Serilog, NLog, log4net, ...) in Prism 8 based on Prism.Plugin.Logging

Hello, I'd like to use Serilog with Prism 8 in my WPF application. To do this I'm creating a plugin with my ISerilogLogger that inherit from IAggregableLogger for using with multiples loggers.
In my App.xaml.cs I resolve SerilogLogger concrete type and I add to AggregateLogger by AddLoggers method.
In my module get IAggregateLogger interface by constructor injection and I get my logger but I can only access to ILogger methods because I can't get my own ISerilogLogger (AddLoggers adds ILogger interface). So is this the right approach to integrate other loggers implementations in Prism 8? Can you provide an example to explain the right approach to use?

Thank you

Luca

Use StringBuilder

StringBuilder has a significant performance advantage against + operators

Add Tests

Description

There have not really been any tests for the Logging Plugin. Much of the Logging Plugin is really hard to test, however there are a number of things that we probably could test such as the logging, helper and registration extensions.

Add support for changing Syslog Formats

Currently only a single standard Syslog Format is supported. Additional formats should be supported.

  • RFC 3164 The BSD syslog Protocol (obsoleted by RFC 5424)
  • RFC 3195 Reliable Delivery for syslog
  • RFC 5424 The Syslog Protocol
  • RFC 5425 TLS Transport Mapping for Syslog
  • RFC 5426 Transmission of Syslog Messages over UDP
  • RFC 5427 Textual Conventions for Syslog Management
  • RFC 5848 Signed Syslog Messages
  • RFC 6012 Datagram Transport Layer Security (DTLS) Transport Mapping for Syslog
  • RFC 6587 Transmission of Syslog Messages over TCP

LogglyHttpLogger raise FileLoadException in Xamarin.Forms.iOS

I noticed that LogglyHttpLogger rise FileLoadException "Could not load file or assembly 'System.Text.Encodings.Web" when used in Xamarin.Forms iOS (works fine in UWP, I didn't test yet in Android). It is because

protected virtual string Tags()
        {
            var encoder = UrlEncoder.Default;
            var tags = new List<string>{
                encoder.Encode(_options.AppName)
            };
            foreach(var tag in _options.Tags)
            {
                tags.Add(encoder.Encode(tag));
            }
            return string.Join(",", tags);
        }

I fixed it in my PR with

 protected virtual string Tags()
        {
            var tags = new List<string>{
                WebUtility.UrlEncode(_options.AppName)
            };
            foreach (var tag in _options.Tags)
            {
                tags.Add(WebUtility.UrlEncode(tag));
            }
            return string.Join(",", tags);
        }

How to register more than one logging service?

i apologize for the newbie question

How do I register more than one logging service, for example: console and Syslog

I tried all the possible values of IfAlreadyRegistered, but only the Replace works,
all the other throw the following exception
DryIoc.ContainerException: Timeout exceeded getting exception details

protected override void RegisterTypes(IContainerRegistry containerRegistry)
      ....
      var container = containerRegistry.GetContainer();

      container.RegisterMany<ConsoleLoggingService>(Reuse.Singleton,
        serviceTypeCondition: t => typeof(ConsoleLoggingService).ImplementsServiceType(t));

      containerRegistry.Register<ISyslogOptions, SyslogOptions>();

      container.RegisterMany<SyslogLogger>(Reuse.Singleton,
        ifAlreadyRegistered: IfAlreadyRegistered.Replace,
        serviceTypeCondition: t => typeof(SyslogLogger).ImplementsServiceType(t));

Add Registration Extensions

Description

Currently each of the loggers require explicit registration. To make this easier to consume registration extensions should be added.

Current

public class AwesomeAppOptions : ISyslogOptions
{
    // e.g. 192.168.0.100
    // e.g. logging.contoso.com
    public string HostNameOrIp => Secrets.LoggingHost;

    // If this is null, the SyslogLogger will use port 514
    public int? Port => int.Parse(Secrets.LoggingPort);

    public string AppNameOrTag => "AwesomeApp"
}

public class App : PrismApplication
{
    protected override void RegisterTypes(IContainerRegistry containerRegistry)
    {
        containerRegistry.Register<ISyslogOptions, AwesomeAppOptions>();

        // Registers the Syslog Logger as a Transient Service
        containerRegistry.Register<ILoggerFacade, SyslogLogger>();
        containerRegistry.Register<ILogger, SyslogLogger>();
    }
}

Proposed

public class App : PrismApplication
{
    protected override void RegisterTypes(IContainerRegistry containerRegistry)
    {
        containerRegistry.RegisterSyslogLogger<AwesomeAppOptions>();

        // OR
        containerRegistry.RegisterSyslogLogger(o => {
            o.HostNameOrIp = Secrets.LoggingHost;
            o.Port = Secrets.LoggingPort;
            o.AppNameOrTag = "Awesome App"
        });
    }
}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.