اتصال برنامه‌هایی که Serilog دارند

در این آموزش
  1. گام ۱: نصب sink
  2. گام ۲: پیکربندی در کد
  3. ⁦ASP.NET Core⁩ با Serilog
  4. پیکربندی از appsettings.json
  5. خطاها و trace_id
  6. پیش از خاموش شدن، Flush کنید
  7. عیب‌یابی
  8. منابع و مطالعهٔ بیشتر

LogMug پروتکل دریافت Seq را می‌فهمد. یعنی برنامه‌ای که Serilog دارد با همان پکیج استاندارد Serilog.Sinks.Seq به LogMug وصل می‌شود؛ نه پکیج اختصاصی لازم است، نه تغییر در جاهایی که لاگ می‌نویسید. فقط مقصد sink (بخشی از Serilog که رویدادها را به یک مقصد می‌نویسد) عوض می‌شود.

گام ۱: نصب sink

dotnet add package Serilog.Sinks.Seq

اگر پروژه هنوز Serilog را به ⁦ASP.NET Core⁩ وصل نکرده، Serilog.AspNetCore را هم نصب کنید. Serilog از netstandard2.0 پشتیبانی می‌کند، پس همین روش روی ⁦.NET Framework 4.6.2⁩ به بعد هم کار می‌کند؛ جزئیات آن در اتصال برنامه‌های ⁦.NET Framework 4.x⁩ آمده است.

گام ۲: پیکربندی در کد

کمینهٔ لازم یک خط WriteTo.Seq است. نشانی را بدون مسیر بدهید؛ sink خودش مسیر /api/events/raw را اضافه می‌کند:

using Serilog;

Log.Logger = new LoggerConfiguration()
    .MinimumLevel.Information()
    .Enrich.FromLogContext()
    .Enrich.WithProperty("Application", "orders-api")
    .Enrich.WithProperty("Environment", "production")
    .WriteTo.Console()
    .WriteTo.Seq("https://ingest.logmug.ir", apiKey: "lm_ingest_...")
    .CreateLogger();

LogMug چند ویژگی را به ستون‌های داشبورد می‌برد:

  • Application (یا ServiceName) نام سرویس می‌شود.
  • Environment محیط می‌شود.
  • MachineName میزبان می‌شود؛ آن را با پکیج Serilog.Enrichers.Environment و .Enrich.WithMachineName() اضافه کنید.

قالب پیام (مثلاً Order {OrderId} paid) جدا ذخیره می‌شود و متن نهایی رندرشده نمایش داده می‌شود. هر ویژگی، مثل OrderId، در داشبورد قابل‌فیلتر است. اگر با لاگ ساخت‌یافته تازه آشنا شده‌اید، مقالهٔ لاگ ساخت‌یافته چیست دلیل اهمیت این تفاوت را توضیح می‌دهد.

⁦ASP.NET Core⁩ با Serilog

در Program.cs با Serilog.AspNetCore:

using Serilog;

var builder = WebApplication.CreateBuilder(args);

builder.Host.UseSerilog((ctx, lc) => lc
    .ReadFrom.Configuration(ctx.Configuration)
    .Enrich.FromLogContext()
    .Enrich.WithProperty("Application", "orders-api")
    .Enrich.WithProperty("Environment", ctx.HostingEnvironment.EnvironmentName)
    .WriteTo.Seq("https://ingest.logmug.ir",
        apiKey: ctx.Configuration["LogMug:Key"]));

var app = builder.Build();
app.UseSerilogRequestLogging();

کلید را از پیکربندی می‌خوانیم تا در کد و مخزن نماند؛ در سرور آن را با متغیر محیطی LogMug__Key تنظیم کنید. UseSerilogRequestLogging برای هر درخواست یک خط خلاصه با مسیر، کد وضعیت و زمان پاسخ می‌نویسد.

پیکربندی از appsettings.json

اگر ترجیح می‌دهید همه‌چیز در پیکربندی باشد (با Serilog.Settings.Configuration که همراه Serilog.AspNetCore نصب می‌شود):

{
  "Serilog": {
    "Using": [ "Serilog.Sinks.Seq" ],
    "MinimumLevel": {
      "Default": "Information",
      "Override": { "Microsoft.AspNetCore": "Warning" }
    },
    "WriteTo": [
      {
        "Name": "Seq",
        "Args": {
          "serverUrl": "https://ingest.logmug.ir",
          "apiKey": "lm_ingest_..."
        }
      }
    ],
    "Properties": { "Application": "orders-api" }
  }
}

در این حالت خط WriteTo.Seq را از کد بردارید تا لاگ‌ها دو بار فرستاده نشوند.

خطاها و trace_id

  • استثنا را همیشه آرگومان اول بدهید: Log.Error(ex, "Payment failed for {OrderId}", id). نوع، پیام و stack trace جدا ذخیره می‌شوند و خطاهای هم‌ریشه گروه‌بندی می‌شوند.
  • در نسخه‌های جدید Serilog (از 3.1 به بعد) شناسهٔ trace و span جاری خودکار روی رویداد ثبت و با sink فرستاده می‌شود؛ پس در ⁦ASP.NET Core⁩ لاگ‌های یک درخواست با هم پیوند می‌خورند. شرح کامل در دنبال کردن یک درخواست.

پیش از خاموش شدن، Flush کنید

sink رویدادها را دسته‌ای و در پس‌زمینه می‌فرستد. در برنامه‌های کنسول و سرویس‌ها، پیش از خروج Log.CloseAndFlush() را صدا بزنید تا آخرین لاگ‌ها، که معمولاً مهم‌ترین‌اند، گم نشوند:

try
{
    // run the app
}
catch (Exception ex)
{
    Log.Fatal(ex, "Application terminated unexpectedly");
}
finally
{
    Log.CloseAndFlush();
}

اگر شبکهٔ سرور ناپایدار است، sink حالت بافر روی دیسک هم دارد: با پارامتر bufferBaseFilename رویدادها اول در فایل نوشته و بعد فرستاده می‌شوند.

عیب‌یابی

Serilog خطاهای sink را بی‌صدا رد می‌کند. برای دیدنشان موقتاً این را در ابتدای برنامه بگذارید:

Serilog.Debugging.SelfLog.Enable(Console.Error);
  • 401: کلید نادرست یا باطل‌شده است. sink کلید را در هدر X-Seq-ApiKey می‌فرستد؛ مقدار apiKey را بررسی کنید.
  • 400: بدنه خوانده نشد؛ نشانی را بدون مسیر اضافه بدهید (فقط https://ingest.logmug.ir) و پراکسی میانی را بررسی کنید.
  • 403: سهمیهٔ ماهانهٔ پلن رایگان تمام شده است.
  • 429 و 503: عبور از نرخ مجاز یا شلوغی موقت؛ sink دسته را نگه می‌دارد و بعداً دوباره می‌فرستد.
  • سرویس default نمایش داده می‌شود: ویژگی Application روی رویدادها نیست؛ Enrich.WithProperty یا Properties در پیکربندی را بررسی کنید.

برای پیکربندی کامل‌تر Serilog، مقالهٔ Serilog در ⁦ASP.NET Core⁩: پیکربندی درست از صفر را ببینید.

منابع و مطالعهٔ بیشتر

  • مخزن Serilog.Sinks.Seq — همهٔ پارامترهای sink از جمله بافر روی دیسک.
  • قالب CLEF — قالب JSON فشرده‌ای که sink با آن رویدادها را می‌فرستد.

کلید پروژه‌تان را هنوز ندارید؟

در پلن رایگان یک پروژه بسازید؛ راهنمای اتصال با نشانی و کلید واقعی خودتان همان‌جا آماده است.

شروع رایگان