SSMS程序集存储过程日志添加与查看问题求助
SQL CLR存储过程日志排查方案
一、适合SQL CLR的日志方法及查看方式
1. 直接通过SqlContext.Pipe输出到SSMS查询窗口
这是最直接的实时排查方式,和你在StoredProcedures里用的方式逻辑一致,能在SSMS查询窗口实时看到日志。
- 注意:异步方法
runWSClient中也可使用,你的代码通过GetAwaiter().GetResult()同步调用,完全兼容该方式。 - 查看位置:执行存储过程的SSMS窗口切换到消息标签页(输出文本日志)或结果标签页(输出
SqlDataRecord格式日志)。
2. 写入SQL Server错误日志
适合记录关键错误或核心运行状态,可通过系统存储过程将日志写入SQL Server自带的错误日志。
- 查看方式:
- SSMS中展开服务器 → 管理 → SQL Server日志 → 双击当前日志查看
- 执行T-SQL查询:
EXEC xp_readerrorlog
3. 写入自定义日志表
创建专属日志表存储日志,适合长期留存和后续分析,需给CLR程序集授予EXTERNAL_ACCESS权限。
- 步骤:
- 先创建日志表:
CREATE TABLE dbo.CLRProcedureLogs ( LogID INT IDENTITY(1,1) PRIMARY KEY, LogTime DATETIME DEFAULT GETDATE(), LogLevel VARCHAR(20), Message NVARCHAR(MAX), ProcedureName NVARCHAR(128) ) - 在CLR代码中通过
SqlConnection插入日志记录。
- 先创建日志表:
4. 写入本地文件(临时排查用)
用System.IO.File类写入本地文件,需确保SQL Server服务账号拥有目标目录的写入权限,仅推荐临时排查使用。
二、针对你的代码的具体修改示例
修改WSClient类,添加多节点日志输出
public class WSClient { public static async Task runWSClient(String value) { using (ClientWebSocket client = new ClientWebSocket()) { Uri servicesUri = new Uri("wss://websocket.kawczynski.eu"); var cTs = new CancellationTokenSource(); cTs.CancelAfter(TimeSpan.FromSeconds(120)); try { // 连接前状态日志 SqlContext.Pipe.Send($"[{DateTime.Now}] 准备连接WebSocket服务器: {servicesUri}"); await client.ConnectAsync(servicesUri, cTs.Token); // 连接状态日志 SqlContext.Pipe.Send($"[{DateTime.Now}] WebSocket当前状态: {client.State}"); if (client.State == WebSocketState.Open) { string message = value; SqlContext.Pipe.Send($"[{DateTime.Now}] 待发送消息内容: {message}"); if (!string.IsNullOrEmpty(message)) { ArraySegment<byte> byteToSend = new ArraySegment<byte>(Encoding.UTF8.GetBytes(message)); await client.SendAsync(byteToSend, WebSocketMessageType.Text, true, cTs.Token); // 发送完成日志 SqlContext.Pipe.Send($"[{DateTime.Now}] 消息发送成功"); } } } catch (WebSocketException e) { // 输出错误到SSMS消息窗口 SqlContext.Pipe.Send($"[{DateTime.Now}] WebSocket异常: {e.Message}"); // 同时写入SQL错误日志 using (SqlConnection conn = new SqlConnection("context connection=true")) { conn.Open(); SqlCommand cmd = new SqlCommand( $"RAISERROR(N'CLR WSClient错误: {e.Message}', 10, 1) WITH LOG;", conn); cmd.ExecuteNonQuery(); } } catch (Exception ex) { // 捕获所有未预料异常 SqlContext.Pipe.Send($"[{DateTime.Now}] 未知异常: {ex.Message}"); } } } }
修改StoredProcedures类,添加调用前后日志
[Microsoft.SqlServer.Server.SqlProcedure] public static void HelloWorld(String value) { Microsoft.SqlServer.Server.SqlMetaData columnInfo = new Microsoft.SqlServer.Server.SqlMetaData("VALUE", SqlDbType.NVarChar, Max); SqlDataRecord greetingRecord = new SqlDataRecord(new Microsoft.SqlServer.Server.SqlMetaData[] { columnInfo }); greetingRecord.SetString(0, value); SqlContext.Pipe.Send(greetingRecord); // WSClient调用前日志 SqlContext.Pipe.Send($"[{DateTime.Now}] 开始执行WSClient调用,传入参数: {value}"); var ws = new WSClient(); WSClient.runWSClient(value).GetAwaiter().GetResult(); // WSClient调用完成日志 SqlContext.Pipe.Send($"[{DateTime.Now}] WSClient调用执行完毕"); }
三、日志查看方式说明
- SSMS消息窗口:执行存储过程后,切换到「消息」标签页,即可查看所有
SqlContext.Pipe.Send输出的文本日志。 - SQL Server错误日志:在SSMS中进入「服务器 → 管理 → SQL Server日志」,双击当前日志就能找到通过
RAISERROR WITH LOG写入的错误信息。 - 自定义日志表:直接执行
SELECT * FROM dbo.CLRProcedureLogs即可查询所有留存的日志记录。
内容的提问来源于stack exchange,提问作者Eva
相关产品推荐
相关产品推荐

