Skip to main content

Logging Agent - C Sharp

Write a log.

Logic TypeAvailable
Generic logic
Aggregator logic

Logs will be collected in the task's task result and look like this:

2023-12-31T12:59:59.000000000+00:00     Info    plaintext       some logging
2024-01-01T01:00:00.000000000+00:00 Error json {"error":true,"errorMessage":"some error","stack":"Error: some error...","taskId":"..."}
info

Logs output with Console.Write() or Console.WriteLine() will not show up in the execution result.

Import and Usage

The agent can be used without using additional namespaces:

public static class Logic
{

public static async Task Run(Context ctx)
{
await LoggingAgent.Info("some logging");
}

public static async Task HandleError(Context ctx, Exception error)
{
await LoggingAgent.Error("some error");
}
}

Class Reference

Type

  • Public static class LoggingAgent

Methods: Write a Log

public async static Task Info(string message) {}
public async static Task Info(object message) {}
ParameterDescription
valueA string message or "JSON" object

Write a log with Info severity level.

warning

Using objects of user-defined class will cause the fields not parsed properly.

Use Dictionary or JsonObject instead.

The methods represent different logging severity levels:

Log TypeSeverity
ErrorHighest
Warn
Info
Debug
TraceLowest

Examples

Write Logs

// log a string
await LoggingAgent.Info("don't panic!");

// log a JSON object
var task = await ctx.GetTask();

await LoggingAgent.Error(
new Dictionary<string, object?>()
{
{ "taskId", task.TaskKey.TaskIdString() },
{ "error", new Dictionary<string, object?>()
{
{ "message", error.Message },
{ "stack", error.StackTrace }
}
},
{ "list", new List<string>()
{
"item 1",
"item 2",
"item 3"
}
}
}
);

// or

/*
- import the following namespace:

using System.Text.Json.Nodes;
*/
await LoggingAgent.Error(
new JsonObject
{
["taskId"] = task.TaskKey.TaskIdString(),
["error"] = new JsonObject
{
["message"] = error.Message,
["stack"] = error.StackTrace
},
["list"] = new JsonArray(
"item 1",
"item 2",
"item 3"
)
}
);

See the example of session storage agent for how to use classes extended from JsonNode.

Log Session/Local Storage Value

You can log the received JsonNode object from session or local storages without any conversion:

JsonNode? data = (await SessionStorageAgent.Get("data"))?.JsonValue;

await LoggingAgent.Info(data);

Advanced Examples

Log User-Defined Classes

Assuming we have a Person and a Job class with its source context class defined:

Import namespace(s) and declare classes
using System.Text.Json;
using System.Text.Json.Nodes;
using System.Text.Json.Serialization;

internal class Person
{
[JsonPropertyName("name")]
public string? Name { get; set; }

[JsonPropertyName("age")]
public int? Age { get; set; }

[JsonPropertyName("job")]
public Job? Job { get; set; }

[JsonPropertyName("quotes")]
public List<string>? Quotes { get; set; }

public Person(string name, int age, Job job, List<string> quotes)
{
Name = name;
Age = age;
Job = job;
Quotes = quotes;
}
}

internal class Job
{
[JsonPropertyName("title")]
public string? Title { get; set; }

[JsonPropertyName("salary")]
public int? Salary { get; set; }

public Job(string title, int salary)
{
Title = title;
Salary = salary;
}
}

// source generation context for Person
[JsonSourceGenerationOptions()]
[JsonSerializable(typeof(Person))]
internal partial class PersonSourceGenerationContext : JsonSerializerContext
{
}

You can convert the object to a JSON string, then convert it to a JsonNode object for the logging agent:

JsonNode personData = JsonNode.Parse(
JsonSerializer.Serialize<Person>(
person,
PersonSourceGenerationContext.Default.Person
)
);

await LoggingAgent.Info(personData);