NET 6 WebAPI - قدم به قدم با Elasticsearch و Kibana
در این مقاله ما dotNet 6 رو با Elk Stack از جمله Elasticsearch ، Kibana و Serilog بررسی میکنیم
ما در این مقاله چه چیزی را پوشش می دهیم
- جستجوی الاستیک چیست
- کیبانا چیست
- چرا از Elasticsearch استفاده کنید
- چگونه همه چیز با هم متناسب است
- شرکت هایی که از ELK استفاده می کنند
- عناصر
- کد نویسی همین مفاهیم
جستجوی الاستیک چیست؟
Elasticsearch یک موتور جستجو و تجزیه و تحلیل open-source و توزیع شده است، Elasticsearch به شما امکان می دهد حجم عظیمی از داده ها را به سرعت و در real-time ذخیره، جستجو و تجزیه و تحلیل کنید و در چند میلی ثانیه پاسخ دهید.
بکارگیری ElasticSearch
- راه خود را جستجو کنید
- در مقیاس بزرگ تجزیه و تحلیل کنید
کیبانا چیست؟
Kibana یک ابزار رابط کاربریه که به شما امکان میده جستجو، visulize، و داشبورد را بر روی داده های گزارش جمع آوری شده در Elasticsearch Cluster بسازید.
ویژگی اصلی کیبانا کوئری و تجزیه و تحلیل داده ها است. علاوه بر این، ویژگیهای تصویرسازی کیبانا به شما امکان میده دادهها رو به طور مداوم به نمایش در بیارید .
با Kibana، درک دادههای بزرگ, آسان است و میتوانید به سرعت داشبوردهای پویا که تغییرات را در جستجوی real-time در Elasticsearch ایجاد میکنند, ایجاد کنید و به اشتراک بگذارید.
چرا از ElasticSearch استفاده کنیم
شروع آسان: کافیست یک فایل docker compose حاوی ظروف ElasticSearch و Kibana را اجرا کنید و آماده شروع لاگ و جستجو هستید.
کوئری آسان: ElasticSearch دارای یک موتور جستجوی full-text بصورت توکار (built-in) است که مبتنی بر Apache Lucene است. در مقایسه با سایر دیتابیسها، کوئری از Lucene آسان است. حتی افراد غیر فنی نیز می توانند کوئریهای رایج را بنویسند.
سرعت: کوئری از یک پایگاه داده بزرگ SQL می تواند به راحتی 10 یا 20 ثانیه طول بکشد. معمولن کوئری های مشابه در پایگاه داده بزرگ ElasticSearch نتایج را در کمتر از 10 میلی ثانیه برگردانند.
رایگان: خوب تقریبا. ویژگی های اصلی رایگان هستند، البته اکثرا. اگر به ویژگیهای امنیتی و هشدار در Kibana نیاز دارید، میتوانید اشتراک تجاری X-pack را برای Kibana خریداری کنید، یا میتوانید برخی از جایگزینهای منبع باز را نصب کنید.
موتور جستجوی Full-Text
ماشین تحلیلی
ElasticSearch : RESTful API یک API RESTful دارد. نتایج کوئری در قالب JSON برگردانده می شوند که کار با آن آسان است. کوئری و درج داده ها از طریق RESTful API به این معنی است که استفاده از هر زبان برنامه نویسی برای کار با ElasticSearch آسان است.
Scalable: مقیاس پذیری آن آسان است.
شرکتهایی که از ELK استفاده میکنن
- Netflix
- Ebay
- Walmart
- Adobe
- Stack Overflow
حالا زمان کدنویسیست
فایل docker-compose.yml ایجاد کنید و کد زیر را در ان بنویسید
version: '3.1'
services:
elasticsearch:
container_name: els
image: docker.elastic.co/elasticsearch/elasticsearch:7.16.1
ports:
- 9200:9200
volumes:
- elasticsearch-data:/usr/share/elasticsearch/data
environment:
- xpack.monitoring.enabled=true
- xpack.watcher.enabled=false
- "ES_JAVA_OPTS=-Xms512m -Xmx512m"
- discovery.type=single-node
networks:
- elastic
kibana:
container_name: kibana
image: docker.elastic.co/kibana/kibana:7.16.1
ports:
- 5601:5601
depends_on:
- els
environment:
- ELASTICSEARCH_URL=http://localhost:9200
networks:
- elastic
networks:
elastic:
driver: bridge
volumes:
elasticsearch-data:
دستور زیر را اجرا کنید
docker-compose up -d |
.
برای اینکه مطمعن بشیم کد بالا کار میکنه این 2 ادرس رو تو مرورگر وارد کنید
- ELS: http://localhost:9200
- Kibana: http://localhost:5601
حالا یه برنامه وب بسازید (با visual studio یا CLI) حالا پکیجهای زیر رو نصب کنید
- dotnet add package Serilog.AspNetCore
- dotnet add package Serilog.Enrichers.Environment
- dotnet add package Serilog.Sinks.Debug
- dotnet add package Serilog.Sinks.Elasticsearch
- dotnet add package Serilog.Exceptions
- dotnet restore
فایل appsettings.jsonرو به شکل زیر اپدیت کنید
{
"Serilog": {
"MinimumLevel": {
"Default": "Information",
"Override": {
"Microsoft": "Information",
"System": "Warning"
}
}
},
"ElasticConfiguration": {
"Uri": "http://localhost:9200"
},
"AllowedHosts": "*"
}
حالا وارد فایل Program.cs بشید و به شکل زیر تغییرش بدید
using System.Reflection;
using Serilog;
using Serilog.Sinks.Elasticsearch;
var builder = WebApplication.CreateBuilder(args);
ConfigureLogging();
builder.Host.UseSerilog();
// Add services to the container.
builder.Services.AddControllersWithViews();
var app = builder.Build();
// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Home/Error");
}
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
app.Run();
void ConfigureLogging()
{
var environment = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT");
var configuration = new ConfigurationBuilder()
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
.AddJsonFile(
$"appsettings.{Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT")}.json",
optional: true)
.Build();
Log.Logger = new LoggerConfiguration()
.Enrich.FromLogContext()
.Enrich.WithExceptionDetails()
.WriteTo.Debug()
.WriteTo.Console()
.WriteTo.Elasticsearch(ConfigureElasticSink(configuration, environment))
.Enrich.WithProperty("Environment", environment)
.ReadFrom.Configuration(configuration)
.CreateLogger();
}
ElasticsearchSinkOptions ConfigureElasticSink(IConfigurationRoot configuration, string environment)
{
return new ElasticsearchSinkOptions(new Uri(configuration["ElasticConfiguration:Uri"]))
{
AutoRegisterTemplate = true,
IndexFormat = $"{Assembly.GetExecutingAssembly().GetName().Name.ToLower().Replace(".", "-")}-{environment?.ToLower().Replace(".", "-")}-{DateTime.UtcNow:yyyy-MM}"
};
}
حالا برنامه رو اجرا کنید
یکپارچه کنید
- روی منو کلیک کنید
- در بخش Analytics روی discover کلیک کنید
- Index pattern ایجاد کنید با مشخصات زیر
- در Name Type: dotnettelk-*
- در قسمت timestamp @timestamp را انتخاب کنید
- رویcreate index pattern کلیک کنید
- حالا به discover برگردید و تمام
حالا میتوانید همه گزارشها را تا کنون در آنجا ببینید
حالا بیاید یک پیام سفارشی ایجاد کنیم، در داخل controller کد زیر رو وارد کنید
[HttpGet(Name = "GetWeatherForecast")]
public IEnumerable<WeatherForecast> Get()
{
_logger.LogInformation("WeatherForecastController Get - this is a nice message to test the logs", DateTime.UtcNow);
return Enumerable.Range(1, 5).Select(index => new WeatherForecast
{
Date = DateTime.Now.AddDays(index),
TemperatureC = Random.Shared.Next(-20, 55),
Summary = Summaries[Random.Shared.Next(Summaries.Length)]
})
.ToArray();
}
اکنون می توانیم با تایپ message: "WeatherForecastController Get"
در کادر جستجو آن را جستجو کنیم
حالا اجازه دهید خطاها را در داخل کنترلر خود آزمایش کنیم
try
{
throw new Exception("Testing exceptions - ML");
}
catch (Exception ex)
{
_logger.LogError(ex, "An unknown error occurred on the Index action of the HomeController");
}