Application Logging - Awesome new feature

Ok this has been brought up before (Here), but I don’t think enough is known about it so here is an expansion on the topic.

This thing is awesome. I will cover 3 different scenarios from the example.

  • Create a default log
  • Create a specific log
  • Create an Application Insights Log (Yes you read that right, it logs to Azure…)

From the help →

You can create custom loggers in both Business Process Management (BPM) directives and Epicor Functions. Typically you create the logger in a functions library that you then call from a BPM directive. The logger generates the application logs. Application logging captures errors and tracks specific Kinetic activity. You define what an application log captures and tracks by creating a custom logger. You can then better locate the causes of issues or capture process calls.

You can find the help from the client by searching like so:

Library

ApplicationLoggingDemo.efxj (8.8 KB)

9 Likes

Creating Default Logs

Code Example

//refs:
//Microsoft.Extensions.Logging.Abstractions.dll
//Microsoft.Extensions.Logging.dll


//using Microsoft.Extensions.Logging;
//using Ice.Logging;



/* Example uses C# 8, so this is wrong for us.
using logger = Ice.Logging.ApplicationLoggerBuilder.CreateDefaultBuilder(this.Session, "LogId")
    .Build();

logger.LogInformation("Log message");
*/



//This is based on the session, so this will write a file called "HelloWorld.log" to the 'EpicorData/Users/UserName/Log/' folder.
//In my case -> 'EpicorData/Users/KLINCECUM/Log/HelloWorld.log'

//In the default logger, this will add '.log' to the name.
string fileName = "HelloWorld";

using (var logger = Ice.Logging.ApplicationLoggerBuilder.CreateDefaultBuilder(this.Session, fileName).Build())
{
    logger.LogInformation("Hello World!");
}

//Pudding ->
var file = new FilePath(ServerFolder.UserData, $"Log/{fileName}.log");

output = Sandbox.IO.File.ReadAllText(file, System.Text.Encoding.UTF8);

Function Tester

Server File Download

Log File

4 Likes

Creating Specific Logs

Code

//refs:
//Microsoft.Extensions.Logging.Abstractions.dll
//Microsoft.Extensions.Logging.dll


//using Microsoft.Extensions.Logging;
//using Ice.Logging;


//This is based on the session, so this will write a file called "SpecificLog.txt" to the 'epicordata/Companies/YOURCOMPANY/Log' folder. (path is not exact)
//In my case -> 'epicordata/SITEID/Companies/YOURCOMPANY/Log/SpecificLog.txt'

//We can use an arbitrary name and extension here.
string fileName = "SpecificLog.txt";

var logger = ApplicationLoggerBuilder.CreateBuilder()
    .SetMinimumLevel(LogLevel.Information)
    .AddFile(
        options =>
        {
            options.Session = this.Session;
            options.FileName = fileName;
            options.Folder = LogFolder.Company;
            options.MessageOptions.QuoteValues = false;
            options.MessageOptions.ShowLogLevel = true;
            options.MessageOptions.TimestampFormat = TimestampFormat.Time;
        })
    .Build();
    
using (logger)
{
    logger.LogInformation("This is a test: {Value}", "test");
    logger.LogError("This is a error test: {Value}", "error");
}


//Pudding ->
var file = new FilePath(ServerFolder.CompanyData, $"Log/{fileName}");

output = Sandbox.IO.File.ReadAllText(file, System.Text.Encoding.UTF8);

Function Tester

Server File Download

Log File

4 Likes

Create an Application Insights Log

Yes, you can log to Azure, right from inside Epicor.
I’ll come back and add some instructions for setting that up in Azure.

Code

//refs:
//Microsoft.Extensions.Logging.Abstractions.dll
//Microsoft.Extensions.Logging.dll
//Microsoft.ApplicationInsights.dll <- For Going Further

//using Microsoft.Extensions.Logging;
//using Ice.Logging;

//Going Further...
//using Microsoft.ApplicationInsights;
//using Microsoft.ApplicationInsights.Extensibility;


/*
From the example ->
const string connectionString = "InstrumentationKey=aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa;IngestionEndpoint=https://centralus-0.in.applicationinsights.azure.com/;LiveEndpoint=https://centralus.livediagnostics.monitor.azure.com/";


using var logger = ApplicationLoggerBuilder.CreateBuilder()
    .AddApplicationInsights(
        options =>
        {
            options.ConnectionString = connectionString;
        })
    .Build();
*/


  //See this beauty... Yep, we can log straight to Azure.
  string connectionString = "Put your own key here, looks similar to below.";
//string connectionString = "InstrumentationKey=aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa;IngestionEndpoint=https://centralus-0.in.applicationinsights.azure.com/;LiveEndpoint=https://centralus.livediagnostics.monitor.azure.com/";

  var logger = ApplicationLoggerBuilder.CreateBuilder()
      .AddApplicationInsights(
          options =>
          {
              options.ConnectionString = connectionString;
          })
      .Build();
    

  using (logger)
  {
      for(int x = 0; x < 10; x++ )
      {
          logger.LogInformation("Azure Logging test: {Value}", x.ToString());
      }
  }
    
  //Or you can go further down the rabbit hole...    
  using (var config = TelemetryConfiguration.CreateDefault())
  {
      config.ConnectionString = connectionString;
      var telemetryClient = new TelemetryClient(config);
  
      telemetryClient.TrackEvent("ThisIsMyCustomEvent");
      telemetryClient.TrackTrace("ThisIsMyCustomTraceLog");
      telemetryClient.TrackException(new Exception("YouSuckException!!!"));    
  }

Kusto Query

Exception expanded

9 Likes

homer simpson eating GIF

2 Likes

I mean, that’s where the proof is :rofl:

This is awesome Kevin.

Give Me Five GIF by SpongeBob SquarePants

1 Like

This seems like it fits in the eggspurts corner

I’ll move it when I’m finished adding stuff.

1 Like

Done!

1 Like

Undone!

4 Likes

This is fantastic! Thank you Kevin!

1 Like

Step 1: Create Your Application Insights Resource

  1. Go to Azure Portal: https://portal.azure.com
  2. Search for “Application Insights” in the top search bar.
  3. Click “Create”.
  4. Fill in the required fields:
  • Subscription and Resource Group
  • Name: e.g., MyERP-Telemetry
  • Region: Choose the same as your application or your desired Azure region.
  • Workspace Details: Choose approptiate value.
  1. Click Review + Create → then Create.

Step 2: Get Your Connection String

Once the resource is created:

  1. Open the resource in Azure.
  2. On the left panel, go to “Overview” or “Properties”.
  3. Copy the Connection String. It looks like this:
InstrumentationKey=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx;IngestionEndpoint=https://<your-region>.in.applicationinsights.azure.com/;LiveEndpoint=https://<your-region>.livediagnostics.monitor.azure.com/

Kusto Queries - Ask ChatGPT :rofl:

1 Like

Where did Sandbox.IO come from? Is that only in cloud or newer than 2024.2?

I get warnings about writing directly to a file using System.IO stuff - I guess there has been other chatter about Epicor removing these at some point (although I can ignore the warnings it does currently work on 2024.2.10):

I saw your code and thought maybe there is a correct way to write to a log file and avoid these warnings, but I tried the ApplicationLogger stuff and wasn’t happy that I couldn’t get it to write to:

\\server\KineticData\EfxLogs\logname.log

Seems like you have to pass in an object of type LogFolder to the options.Folder and not sure if I can get my own arbitrary folder a few levels up to be part of that path.

My “problem” with LogFolder.Company (e.g. \\server\KineticData\Companies\MYCOMPANY\Log\) is that it is already full of ImportEDI logs, and other noise.

Thanks for the cool share!

1 Like