diff --git a/src/content/docs/how-to/monitoring/monitor-command.mdx b/src/content/docs/how-to/monitoring/monitor-command.mdx index 99031092..30700985 100644 --- a/src/content/docs/how-to/monitoring/monitor-command.mdx +++ b/src/content/docs/how-to/monitoring/monitor-command.mdx @@ -7,7 +7,7 @@ import { Tabs, TabItem } from '@astrojs/starlight/components'; The MONITOR command streams every command processed by the Valkey server back to the client in real time. It is intended for debugging and development only. -MONITOR is supported in Python, Node.js, Java, and Go clients. C# and PHP support is not yet available. +MONITOR is supported in Python, Node.js, Java, Go, and C# clients. PHP support is not yet available. ## How It Works @@ -113,6 +113,29 @@ There are two modes for consuming monitor messages: } ``` + + + :::note + The C# client uses `IAsyncEnumerable` instead of callbacks. Messages are consumed via `await foreach` with native cancellation support. + ::: + + ```csharp + using Valkey.Glide; + + // Create a MonitorConfig (implements IDisposable for secure credential handling) + using var config = new MonitorConfig("localhost", 6379); + + // Create the monitor client + await using var monitor = await MonitorClient.CreateClient(config); + + // Consume messages as an async stream with cancellation support + using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(30)); + await foreach (MonitorMessage msg in monitor.GetMessagesAsync(cts.Token)) + { + Console.WriteLine($"{msg.Timestamp:O} [{msg.Database}] {msg.ClientAddress} {msg.Command} {string.Join(" ", msg.Args)}"); + } + ``` + ### Queue mode @@ -196,8 +219,45 @@ There are two modes for consuming monitor messages: } ``` + + + :::note + The C# client does not have a separate queue mode. `GetMessagesAsync()` returns an `IAsyncEnumerable` that can be consumed one message at a time or as a continuous stream. + ::: + + ```csharp + using Valkey.Glide; + + // Create a MonitorConfig (implements IDisposable for secure credential handling) + using var config = new MonitorConfig("localhost", 6379); + + // Create the monitor client + await using var monitor = await MonitorClient.CreateClient(config); + + // Consume messages as an async stream with cancellation support + using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(30)); + await foreach (MonitorMessage msg in monitor.GetMessagesAsync(cts.Token)) + { + Console.WriteLine($"{msg.Timestamp:O} [{msg.Database}] {msg.ClientAddress} {msg.Command} {string.Join(" ", msg.Args)}"); + } + ``` + +## C# Configuration + +The C# client uses the `MonitorConfig` fluent API for connection configuration: + +```csharp +using var config = new MonitorConfig("localhost", 6379) + .WithTls() // Enable TLS + .WithAuth("password") // Password-only auth + .WithAuth("user", "password") // Username + password auth + .WithDatabase(2); // Select database +``` + +Note: `MonitorConfig` implements `IDisposable` — it clears the password array on dispose for secure credential handling. + ## Monitor Message Fields Each monitor message contains the following fields: @@ -209,3 +269,15 @@ Each monitor message contains the following fields: | `clientAddr` | string | Address of the client that issued the command | | `command` | string | Command name | | `args` | list/array | Command arguments | + +## C# Type Mapping + +In the C# client, `MonitorMessage` is a strongly-typed class: + +| Property | Type | +| --- | --- | +| `Timestamp` | `DateTimeOffset` | +| `Database` | `ushort` | +| `ClientAddress` | `string` | +| `Command` | `string` | +| `Args` | `IReadOnlyList` | diff --git a/src/data/available-commands.json b/src/data/available-commands.json index dee5bc81..5eb6067a 100644 --- a/src/data/available-commands.json +++ b/src/data/available-commands.json @@ -380,7 +380,7 @@ { "command": "MODULE LOAD", "valkey-io": "/commands/module-load", "python": "not_available", "node": "not_available", "java": "not_available", "go": "not_available", "csharp": "not_available", "php": "not_available", "python-href": "https://github.com/valkey-io/valkey-glide/issues/6292", "node-href": "https://github.com/valkey-io/valkey-glide/issues/6292", "java-href": "https://github.com/valkey-io/valkey-glide/issues/6292", "go-href": "https://github.com/valkey-io/valkey-glide/issues/6292", "csharp-href": "https://github.com/valkey-io/valkey-glide/issues/6292", "php-href": "https://github.com/valkey-io/valkey-glide/issues/6292" }, { "command": "MODULE LOADEX", "valkey-io": "/commands/module-loadex", "python": "not_available", "node": "not_available", "java": "not_available", "go": "not_available", "php": "not_available", "csharp": "not_available", "python-href": "https://github.com/valkey-io/valkey-glide/issues/6292", "node-href": "https://github.com/valkey-io/valkey-glide/issues/6292", "java-href": "https://github.com/valkey-io/valkey-glide/issues/6292", "go-href": "https://github.com/valkey-io/valkey-glide/issues/6292", "csharp-href": "https://github.com/valkey-io/valkey-glide/issues/6292", "php-href": "https://github.com/valkey-io/valkey-glide/issues/6292" }, { "command": "MODULE UNLOAD", "valkey-io": "/commands/module-unload", "python": "not_available", "node": "not_available", "java": "not_available", "go": "not_available", "csharp": "not_available", "php": "not_available", "python-href": "https://github.com/valkey-io/valkey-glide/issues/6292", "node-href": "https://github.com/valkey-io/valkey-glide/issues/6292", "java-href": "https://github.com/valkey-io/valkey-glide/issues/6292", "go-href": "https://github.com/valkey-io/valkey-glide/issues/6292", "csharp-href": "https://github.com/valkey-io/valkey-glide/issues/6292", "php-href": "https://github.com/valkey-io/valkey-glide/issues/6292" }, - { "command": "MONITOR", "valkey-io": "/commands/monitor", "python": "available", "node": "available", "java": "available", "go": "available", "csharp": "not_available", "php": "not_available", "python-href": "/how-to/monitoring/monitor-command", "node-href": "/how-to/monitoring/monitor-command", "java-href": "/how-to/monitoring/monitor-command", "go-href": "/how-to/monitoring/monitor-command", "csharp-href": "https://github.com/valkey-io/valkey-glide/issues/5978", "php-href": "https://github.com/valkey-io/valkey-glide/issues/5978" }, + { "command": "MONITOR", "valkey-io": "/commands/monitor", "python": "available", "node": "available", "java": "available", "go": "available", "csharp": "available", "php": "not_available", "python-href": "/how-to/monitoring/monitor-command", "node-href": "/how-to/monitoring/monitor-command", "java-href": "/how-to/monitoring/monitor-command", "go-href": "/how-to/monitoring/monitor-command", "csharp-href": "/how-to/monitoring/monitor-command", "php-href": "https://github.com/valkey-io/valkey-glide/issues/5978" }, { "command": "PSYNC", "valkey-io": "/commands/psync", "python": "not_available", "node": "not_available", "java": "not_available", "go": "not_available", "csharp": "not_available", "php": "not_available", "href": "#incompatible-commands" }, { "command": "REPLCONF", "valkey-io": "/commands/replconf", "python": "not_available", "node": "not_available", "java": "not_available", "go": "not_available", "csharp": "not_available", "php": "not_available", "python-href": "https://github.com/valkey-io/valkey-glide/issues/6292", "node-href": "https://github.com/valkey-io/valkey-glide/issues/6292", "java-href": "https://github.com/valkey-io/valkey-glide/issues/6292", "go-href": "https://github.com/valkey-io/valkey-glide/issues/6292", "csharp-href": "https://github.com/valkey-io/valkey-glide/issues/6292", "php-href": "https://github.com/valkey-io/valkey-glide/issues/6292" }, { "command": "REPLICAOF", "valkey-io": "/commands/replicaof", "python": "available", "node": "available", "java": "available", "go": "available", "csharp": "not_available", "php": "not_available", "python-href": "https://github.com/valkey-io/valkey-glide/issues/6292", "node-href": "https://github.com/valkey-io/valkey-glide/issues/6292", "go-href": "https://github.com/valkey-io/valkey-glide/issues/6292", "csharp-href": "https://github.com/valkey-io/valkey-glide/issues/6292", "php-href": "https://github.com/valkey-io/valkey-glide/issues/6292" },