From 2b09c8d1f8868c22f8d3b6af30a492ef1ac9569c Mon Sep 17 00:00:00 2001 From: SteveGibson <100594800+SteveBoytsun@users.noreply.github.com> Date: Mon, 23 Sep 2024 14:04:32 -0400 Subject: [PATCH] Logging API (#1714) Co-authored-by: Steve Boytsun --- .../Codegen.Tests/fixtures/server/Lib.cs | 4 +- .../bindings-csharp/Runtime/Internal/FFI.cs | 18 +- .../Runtime/Internal/Module.cs | 2 +- crates/bindings-csharp/Runtime/Log.cs | 179 ++++++++++++++++++ crates/bindings-csharp/Runtime/Runtime.cs | 38 ---- .../src/subcommands/project/csharp/Lib._cs | 6 +- modules/benchmarks-cs/circles.cs | 10 +- modules/benchmarks-cs/ia_loop.cs | 12 +- modules/benchmarks-cs/synthetic.cs | 14 +- modules/spacetimedb-quickstart-cs/Lib.cs | 6 +- 10 files changed, 217 insertions(+), 72 deletions(-) create mode 100644 crates/bindings-csharp/Runtime/Log.cs diff --git a/crates/bindings-csharp/Codegen.Tests/fixtures/server/Lib.cs b/crates/bindings-csharp/Codegen.Tests/fixtures/server/Lib.cs index cace016747..32bbc78912 100644 --- a/crates/bindings-csharp/Codegen.Tests/fixtures/server/Lib.cs +++ b/crates/bindings-csharp/Codegen.Tests/fixtures/server/Lib.cs @@ -84,10 +84,10 @@ public static partial class Reducers public static void InsertData(PublicTable data) { data.Insert(); - Runtime.Log("New list"); + Log.Info("New list"); foreach (var item in PublicTable.Iter()) { - Runtime.Log($"Item: {item.StringField}"); + Log.Info($"Item: {item.StringField}"); } } diff --git a/crates/bindings-csharp/Runtime/Internal/FFI.cs b/crates/bindings-csharp/Runtime/Internal/FFI.cs index aa9ee4c957..444a90b6c2 100644 --- a/crates/bindings-csharp/Runtime/Internal/FFI.cs +++ b/crates/bindings-csharp/Runtime/Internal/FFI.cs @@ -108,12 +108,6 @@ public readonly struct IndexType private readonly byte index_type; } - [StructLayout(LayoutKind.Sequential)] - public readonly struct LogLevel(byte log_level) - { - private readonly byte log_level = log_level; - } - [StructLayout(LayoutKind.Sequential)] public readonly record struct RowIter(uint Handle) { @@ -198,9 +192,19 @@ public static partial void _volatile_nonatomic_schedule_immediate( uint args_len ); + public enum LogLevel : byte + { + Error = 0, + Warn = 1, + Info = 2, + Debug = 3, + Trace = 4, + Panic = 5, + } + [LibraryImport(StdbNamespace)] public static partial void _console_log( - byte level, + LogLevel level, [In] byte[] target, uint target_len, [In] byte[] filename, diff --git a/crates/bindings-csharp/Runtime/Internal/Module.cs b/crates/bindings-csharp/Runtime/Internal/Module.cs index 2df5e436ed..425331c015 100644 --- a/crates/bindings-csharp/Runtime/Internal/Module.cs +++ b/crates/bindings-csharp/Runtime/Internal/Module.cs @@ -165,7 +165,7 @@ public static void __describe_module__(BytesSink description) } catch (Exception e) { - Runtime.Log($"Error while describing the module: {e}", Runtime.LogLevel.Error); + Log.Error($"Error while describing the module: {e}"); } } diff --git a/crates/bindings-csharp/Runtime/Log.cs b/crates/bindings-csharp/Runtime/Log.cs new file mode 100644 index 0000000000..400170c46c --- /dev/null +++ b/crates/bindings-csharp/Runtime/Log.cs @@ -0,0 +1,179 @@ +namespace SpacetimeDB; + +using System.Runtime.CompilerServices; +using System.Text; +using SpacetimeDB.Internal; + +public static class Log +{ + /// + /// Write an error message to module log + /// + /// Message to log + /// !!! DO NOT USE !!! Value for this parameter will be automatically generated at compile time. Providing this parameter could lead to undefined behavior + /// !!! DO NOT USE !!! Value for this parameter will be automatically generated at compile time. Providing this parameter could lead to undefined behavior + /// !!! DO NOT USE !!! Value for this parameter will be automatically generated at compile time. Providing this parameter could lead to undefined behavior + public static void Debug( + string message, + [CallerMemberName] string RESERVED_target = "", + [CallerFilePath] string RESERVED_filename = "", + [CallerLineNumber] uint RESERVED_lineNumber = 0 + ) => + LogInternal( + message, + FFI.LogLevel.Debug, + RESERVED_target, + RESERVED_filename, + RESERVED_lineNumber + ); + + /// + /// Write a trace message to module log + /// + /// Message to log + /// !!! DO NOT USE !!! Value for this parameter will be automatically generated at compile time. Providing this parameter could lead to undefined behavior + /// !!! DO NOT USE !!! Value for this parameter will be automatically generated at compile time. Providing this parameter could lead to undefined behavior + /// !!! DO NOT USE !!! Value for this parameter will be automatically generated at compile time. Providing this parameter could lead to undefined behavior + public static void Trace( + string message, + [CallerMemberName] string RESERVED_target = "", + [CallerFilePath] string RESERVED_filename = "", + [CallerLineNumber] uint RESERVED_lineNumber = 0 + ) => + LogInternal( + message, + FFI.LogLevel.Trace, + RESERVED_target, + RESERVED_filename, + RESERVED_lineNumber + ); + + /// + /// Write an info message to module log + /// + /// Message to log + /// !!! DO NOT USE !!! Value for this parameter will be automatically generated at compile time. Providing this parameter could lead to undefined behavior + /// !!! DO NOT USE !!! Value for this parameter will be automatically generated at compile time. Providing this parameter could lead to undefined behavior + /// !!! DO NOT USE !!! Value for this parameter will be automatically generated at compile time. Providing this parameter could lead to undefined behavior + public static void Info( + string message, + [CallerMemberName] string RESERVED_target = "", + [CallerFilePath] string RESERVED_filename = "", + [CallerLineNumber] uint RESERVED_lineNumber = 0 + ) => + LogInternal( + message, + FFI.LogLevel.Info, + RESERVED_target, + RESERVED_filename, + RESERVED_lineNumber + ); + + /// + /// Write a warning message to module log + /// + /// Message to log + /// !!! DO NOT USE !!! Value for this parameter will be automatically generated at compile time. Providing this parameter could lead to undefined behavior + /// !!! DO NOT USE !!! Value for this parameter will be automatically generated at compile time. Providing this parameter could lead to undefined behavior + /// !!! DO NOT USE !!! Value for this parameter will be automatically generated at compile time. Providing this parameter could lead to undefined behavior + public static void Warn( + string message, + [CallerMemberName] string RESERVED_target = "", + [CallerFilePath] string RESERVED_filename = "", + [CallerLineNumber] uint RESERVED_lineNumber = 0 + ) => + LogInternal( + message, + FFI.LogLevel.Warn, + RESERVED_target, + RESERVED_filename, + RESERVED_lineNumber + ); + + /// + /// Write an error message to module log + /// + /// Message to log + /// !!! DO NOT USE !!! Value for this parameter will be automatically generated at compile time. Providing this parameter could lead to undefined behavior + /// !!! DO NOT USE !!! Value for this parameter will be automatically generated at compile time. Providing this parameter could lead to undefined behavior + /// !!! DO NOT USE !!! Value for this parameter will be automatically generated at compile time. Providing this parameter could lead to undefined behavior + public static void Error( + string message, + [CallerMemberName] string RESERVED_target = "", + [CallerFilePath] string RESERVED_filename = "", + [CallerLineNumber] uint RESERVED_lineNumber = 0 + ) => + LogInternal( + message, + FFI.LogLevel.Error, + RESERVED_target, + RESERVED_filename, + RESERVED_lineNumber + ); + + /// + /// Write an exception message to module log + /// + /// Message to log + /// !!! DO NOT USE !!! Value for this parameter will be automatically generated at compile time. Providing this parameter could lead to undefined behavior + /// !!! DO NOT USE !!! Value for this parameter will be automatically generated at compile time. Providing this parameter could lead to undefined behavior + /// !!! DO NOT USE !!! Value for this parameter will be automatically generated at compile time. Providing this parameter could lead to undefined behavior + public static void Exception( + string message, + [CallerMemberName] string RESERVED_target = "", + [CallerFilePath] string RESERVED_filename = "", + [CallerLineNumber] uint RESERVED_lineNumber = 0 + ) => + LogInternal( + message, + FFI.LogLevel.Error, + RESERVED_target, + RESERVED_filename, + RESERVED_lineNumber + ); + + /// + /// Write an exception message and stacktrace to module log + /// + /// Exception to log + /// !!! DO NOT USE !!! Value for this parameter will be automatically generated at compile time. Providing this parameter could lead to undefined behavior + /// !!! DO NOT USE !!! Value for this parameter will be automatically generated at compile time. Providing this parameter could lead to undefined behavior + /// !!! DO NOT USE !!! Value for this parameter will be automatically generated at compile time. Providing this parameter could lead to undefined behavior + public static void Exception( + Exception exception, + [CallerMemberName] string RESERVED_target = "", + [CallerFilePath] string RESERVED_filename = "", + [CallerLineNumber] uint RESERVED_lineNumber = 0 + ) => + LogInternal( + exception.ToString(), + FFI.LogLevel.Error, + RESERVED_target, + RESERVED_filename, + RESERVED_lineNumber + ); + + private static void LogInternal( + string text, + FFI.LogLevel level, + string target, + string filename, + uint lineNumber + ) + { + var target_bytes = Encoding.UTF8.GetBytes(target); + var filename_bytes = Encoding.UTF8.GetBytes(filename); + var text_bytes = Encoding.UTF8.GetBytes(text); + + FFI._console_log( + level, + target_bytes, + (uint)target_bytes.Length, + filename_bytes, + (uint)filename_bytes.Length, + lineNumber, + text_bytes, + (uint)text_bytes.Length + ); + } +} diff --git a/crates/bindings-csharp/Runtime/Runtime.cs b/crates/bindings-csharp/Runtime/Runtime.cs index c1afcfe3c7..054b0fbbb5 100644 --- a/crates/bindings-csharp/Runtime/Runtime.cs +++ b/crates/bindings-csharp/Runtime/Runtime.cs @@ -3,7 +3,6 @@ namespace SpacetimeDB; using System.Runtime.CompilerServices; using SpacetimeDB.BSATN; using SpacetimeDB.Internal; -using static System.Text.Encoding; public class ReducerContext { @@ -82,40 +81,3 @@ public AlgebraicType GetAlgebraicType(ITypeRegistrar registrar) => ); } } - -public static class Runtime -{ - public enum LogLevel : byte - { - Error, - Warn, - Info, - Debug, - Trace, - Panic, - } - - public static void Log( - string text, - LogLevel level = LogLevel.Info, - [CallerMemberName] string target = "", - [CallerFilePath] string filename = "", - [CallerLineNumber] uint lineNumber = 0 - ) - { - var target_bytes = UTF8.GetBytes(target); - var filename_bytes = UTF8.GetBytes(filename); - var text_bytes = UTF8.GetBytes(text); - - FFI._console_log( - (byte)level, - target_bytes, - (uint)target_bytes.Length, - filename_bytes, - (uint)filename_bytes.Length, - lineNumber, - text_bytes, - (uint)text_bytes.Length - ); - } -} diff --git a/crates/cli/src/subcommands/project/csharp/Lib._cs b/crates/cli/src/subcommands/project/csharp/Lib._cs index 874b90f91a..83f83490ef 100644 --- a/crates/cli/src/subcommands/project/csharp/Lib._cs +++ b/crates/cli/src/subcommands/project/csharp/Lib._cs @@ -16,7 +16,7 @@ static partial class Module { var person = new Person { Name = name, Age = age }; person.Insert(); - Runtime.Log($"Inserted {person.Name} under #{person.Id}"); + Log.Info($"Inserted {person.Name} under #{person.Id}"); } [SpacetimeDB.Reducer] @@ -24,8 +24,8 @@ static partial class Module { foreach (var person in Person.Iter()) { - Runtime.Log($"Hello, {person.Name}!"); + Log.Info($"Hello, {person.Name}!"); } - Runtime.Log("Hello, World!"); + Log.Info("Hello, World!"); } } diff --git a/modules/benchmarks-cs/circles.cs b/modules/benchmarks-cs/circles.cs index cb94f42f9a..c13b46eb17 100644 --- a/modules/benchmarks-cs/circles.cs +++ b/modules/benchmarks-cs/circles.cs @@ -65,7 +65,7 @@ public static void insert_bulk_entity(uint count) { new Entity(0, id, id + 5, id * 5).Insert(); } - Runtime.Log($"INSERT ENTITY: {count}"); + Log.Info($"INSERT ENTITY: {count}"); } [SpacetimeDB.Reducer] @@ -75,7 +75,7 @@ public static void insert_bulk_circle(uint count) { new Circle(id, id, id, id + 5, id * 5).Insert(); } - Runtime.Log($"INSERT CIRCLE: {count}"); + Log.Info($"INSERT CIRCLE: {count}"); } [SpacetimeDB.Reducer] @@ -85,7 +85,7 @@ public static void insert_bulk_food(uint count) { new Food(id).Insert(); } - Runtime.Log($"INSERT FOOD: {count}"); + Log.Info($"INSERT FOOD: {count}"); } [SpacetimeDB.Reducer] @@ -103,7 +103,7 @@ public static void cross_join_all(uint expected) } } - Runtime.Log($"CROSS JOIN ALL: {expected}, processed: {count}"); + Log.Info($"CROSS JOIN ALL: {expected}, processed: {count}"); } [SpacetimeDB.Reducer] @@ -127,7 +127,7 @@ public static void cross_join_circle_food(uint expected) } } - Runtime.Log($"CROSS JOIN CIRCLE FOOD: {expected}, processed: {count}"); + Log.Info($"CROSS JOIN CIRCLE FOOD: {expected}, processed: {count}"); } [SpacetimeDB.Reducer] diff --git a/modules/benchmarks-cs/ia_loop.cs b/modules/benchmarks-cs/ia_loop.cs index 74e309b16a..56a6afaf50 100644 --- a/modules/benchmarks-cs/ia_loop.cs +++ b/modules/benchmarks-cs/ia_loop.cs @@ -138,7 +138,7 @@ public static void InsertBulkPosition(uint count) { new Position(id, id, id + 5, id * 5).Insert(); } - Runtime.Log($"INSERT POSITION: {count}"); + Log.Info($"INSERT POSITION: {count}"); } [SpacetimeDB.Reducer] @@ -148,7 +148,7 @@ public static void InsertBulkVelocity(uint count) { new Velocity(id, id, id + 5, id * 5).Insert(); } - Runtime.Log($"INSERT VELOCITY: {count}"); + Log.Info($"INSERT VELOCITY: {count}"); } [SpacetimeDB.Reducer] @@ -166,7 +166,7 @@ public static void update_position_all(uint expected) Position.UpdateByentity_id(position.entity_id, newPosition); count++; } - Runtime.Log($"UPDATE POSITION ALL: {expected}, processed: {count}"); + Log.Info($"UPDATE POSITION ALL: {expected}, processed: {count}"); } [SpacetimeDB.Reducer] @@ -187,7 +187,7 @@ public static void update_position_with_velocity(uint expected) Position.UpdateByentity_id(position.entity_id, position); count++; } - Runtime.Log($"UPDATE POSITION BY VELOCITY: {expected}, processed: {count}"); + Log.Info($"UPDATE POSITION BY VELOCITY: {expected}, processed: {count}"); } [SpacetimeDB.Reducer] @@ -223,7 +223,7 @@ public static void insert_world(ulong players) (int)i ).Insert(); } - Runtime.Log($"INSERT WORLD PLAYERS: {players}"); + Log.Info($"INSERT WORLD PLAYERS: {players}"); } public static List GetTargetablesNearQuad( @@ -346,7 +346,7 @@ public static void game_loop_enemy_ia(ulong players) count++; } - Runtime.Log($"ENEMY IA LOOP PLAYERS: {players}, processed: {count}"); + Log.Info($"ENEMY IA LOOP PLAYERS: {players}, processed: {count}"); } [SpacetimeDB.Reducer] diff --git a/modules/benchmarks-cs/synthetic.cs b/modules/benchmarks-cs/synthetic.cs index 4a39ab5617..0ee4b181cb 100644 --- a/modules/benchmarks-cs/synthetic.cs +++ b/modules/benchmarks-cs/synthetic.cs @@ -418,37 +418,37 @@ public static void clear_table_btree_each_column_u32_u64_u64() [SpacetimeDB.Reducer] public static void count_unique_0_u32_u64_str() { - Runtime.Log("COUNT: " + unique_0_u32_u64_str.Iter().Count()); + Log.Info("COUNT: " + unique_0_u32_u64_str.Iter().Count()); } [SpacetimeDB.Reducer] public static void count_no_index_u32_u64_str() { - Runtime.Log("COUNT: " + no_index_u32_u64_str.Iter().Count()); + Log.Info("COUNT: " + no_index_u32_u64_str.Iter().Count()); } [SpacetimeDB.Reducer] public static void count_btree_each_column_u32_u64_str() { - Runtime.Log("COUNT: " + btree_each_column_u32_u64_str.Iter().Count()); + Log.Info("COUNT: " + btree_each_column_u32_u64_str.Iter().Count()); } [SpacetimeDB.Reducer] public static void count_unique_0_u32_u64_u64() { - Runtime.Log("COUNT: " + unique_0_u32_u64_u64.Iter().Count()); + Log.Info("COUNT: " + unique_0_u32_u64_u64.Iter().Count()); } [SpacetimeDB.Reducer] public static void count_no_index_u32_u64_u64() { - Runtime.Log("COUNT: " + no_index_u32_u64_u64.Iter().Count()); + Log.Info("COUNT: " + no_index_u32_u64_u64.Iter().Count()); } [SpacetimeDB.Reducer] public static void count_btree_each_column_u32_u64_u64() { - Runtime.Log("COUNT: " + btree_each_column_u32_u64_u64.Iter().Count()); + Log.Info("COUNT: " + btree_each_column_u32_u64_u64.Iter().Count()); } // ---------- module-specific stuff ---------- @@ -498,7 +498,7 @@ public static void print_many_things(uint n) { for (int i = 0; i < n; i++) { - Runtime.Log("hello again!"); + Log.Info("hello again!"); } } } diff --git a/modules/spacetimedb-quickstart-cs/Lib.cs b/modules/spacetimedb-quickstart-cs/Lib.cs index 42039ccb73..dabc9ab977 100644 --- a/modules/spacetimedb-quickstart-cs/Lib.cs +++ b/modules/spacetimedb-quickstart-cs/Lib.cs @@ -22,9 +22,9 @@ public static void SayHello() { foreach (var person in Person.Iter()) { - Runtime.Log($"Hello, {person.Name}!"); + Log.Info($"Hello, {person.Name}!"); } - Runtime.Log("Hello, World!"); + Log.Info("Hello, World!"); } [SpacetimeDB.Reducer("list_over_age")] @@ -32,7 +32,7 @@ public static void ListOverAge(byte age) { foreach (var person in Person.Query(person => person.Age >= age)) { - Runtime.Log($"{person.Name} has age {person.Age} >= {age}"); + Log.Info($"{person.Name} has age {person.Age} >= {age}"); } } }