I want to call a stored procedure using Serilog. I am aware that there is no such sink so I am creating a custom Sink. I have my logic to call the stored procedure inside the Emit method of the StoredProcedureSink that implements ILogEventSink. Now, this stored procedure returns a value. How can I get this value when I use Log.Information();
class StoredProcedureSink : ILogEventSink
{
private string _connectionString;
public StoredProcedureSink(string connectionString)
{
_connectionString = connectionString;
}
public void Emit(LogEvent logEvent)
{
var conn = new SqlConnection(_connectionString);
conn.Open();
SqlCommand cmd = new SqlCommand(logEvent.MessageTemplate.ToString().Substring(0, logEvent.MessageTemplate.ToString().IndexOf('{')), conn);
cmd.CommandType = CommandType.StoredProcedure;
var properties = logEvent.Properties.GetValueOrDefault("SqlParams");
var json = JObject.Parse(properties.ToString().Substring(properties.ToString().IndexOf('{') - 1));
foreach(var kvp in json)
{
cmd.Parameters.Add(new SqlParameter(kvp.Key, ((JValue)kvp.Value).Value));
}
cmd.ExecuteNonQuery();
//I would like to read the value returned by the stored proc.
}
}
//I have a wrapper DBLogger in which I configure the serilog. I have published DBLogger as a nuget package so I can use it in all my apps.
public class DBLogger()
{
public DBLogger()
{
Log.Logger = new LoggerConfiguration()
.MinimumLevel.Information()
.MinimumLevel.Override("Microsoft", LogEventLevel.Warning)
.Enrich.FromLogContext()
.WriteTo.StoredProcedureSink(
"connectionString")
.CreateLogger();
}
public void Information(string storedProcedureName, T parameters)
{
try
{
Log.Information(storedProcedureName, parameters);
}
catch (Exception ex)
{
Log.Fatal(ex, "Host terminated unexpectedly");
}
}
}
public class Program
{
static void Main()
{
var logger = new DBLogger();
logger.Information("storedProcedureName", params); //need the Id returned by the stored proc here.
}
}
答案 0 :(得分:0)
使用普通的Serilog模型实际上不太可能。
标准处理包括将LogEvent
捕获在主线程上,然后依次提供给每个接收器-通常是异步的,并且经常对其进行缓冲。
另一个问题是,通常来说,接收器也绝对不会向调用方传播异常(有审核日志记录,但即使这样也不打算用于此类通信)。
在我看来,您要完成的审计工作与Serilog的最佳位置有些距离(不过,我可能是错的-如果是,请在问题中添加更多详细信息)。
如果绝对必须这样做,则可以在登录时添加一个Enricher,该Enricher将回调Action
隔离到LogEvent的Properties中,并将其传递回去。不过,在进行此操作之前,请您三思而后行!
答案 1 :(得分:0)
{% set photo = (musicien.photo) ? musicien.photo : 'your_default_photo' %}
<td><img class="img-vignette" src="data:image/jpeg;base64,{{ photo }}"/></td>