
ΠΠΎΠ³Π²Π°Π½Π΅ΡΠΎ Π΅ ΠΌΠ½ΠΎΠ³ΠΎ Π²Π°ΠΆΠ΅Π½ ΠΈΠ½ΡΡΡΡΠΌΠ΅Π½Ρ Π·Π° ΡΠ°Π·ΡΠ°Π±ΠΎΡΡΠΈΠΊΠ°, Π½ΠΎ ΠΏΡΠΈ ΡΡΠ·Π΄Π°Π²Π°Π½Π΅ΡΠΎ Π½Π° ΡΠ°Π·ΠΏΡΠ΅Π΄Π΅Π»Π΅Π½ΠΈ ΡΠΈΡΡΠ΅ΠΌΠΈ, ΡΠΎ ΡΡΠ°Π²Π° ΠΎΡΠ½ΠΎΠ²Π΅Π½ Π΅Π»Π΅ΠΌΠ΅Π½Ρ, ΠΊΠΎΠΉΡΠΎ ΡΡΡΠ±Π²Π° Π΄Π° Π±ΡΠ΄Π΅ Π·Π°Π»ΠΎΠΆΠ΅Π½ Π² ΠΎΡΠ½ΠΎΠ²Π°ΡΠ° Π½Π° ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ΡΠΎ Π²ΠΈ, Π² ΠΏΡΠΎΡΠΈΠ²Π΅Π½ ΡΠ»ΡΡΠ°ΠΉ ΡΠ»ΠΎΠΆΠ½ΠΎΡΡΡΠ° Π½Π° ΡΠ°Π·ΡΠ°Π±ΠΎΡΠΊΠ°ΡΠ° Π½Π° ΠΌΠΈΠΊΡΠΎΡΠ΅ΡΠ²ΠΈΠ·ΠΈ Π±ΡΡΠ·ΠΎ ΡΠ΅ ΡΠ΅ ΠΏΡΠΎΡΠ²ΠΈ.
Π .Net Core 3 Π±Π΅ΡΠ΅ Π΄ΠΎΠ±Π°Π²Π΅Π½Π° ΠΎΡΠ»ΠΈΡΠ½Π° , ΡΠ°ΠΊΠ° ΡΠ΅ Π°ΠΊΠΎ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡΡΠ° Π²ΠΈ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Ρ Π΄ΠΈΡΠ΅ΠΊΡΠ½ΠΈ HTTP ΠΈΠ·Π²ΠΈΠΊΠ²Π°Π½ΠΈΡ Π·Π° Π²Π·Π°ΠΈΠΌΠΎΠ΄Π΅ΠΉΡΡΠ²ΠΈΠ΅ ΠΌΠ΅ΠΆΠ΄Ρ ΡΡΠ»ΡΠ³ΠΈ, ΠΌΠΎΠΆΠ΅ΡΠ΅ Π΄Π° ΡΠ΅ Π²ΡΠ·ΠΏΠΎΠ»Π·Π²Π°ΡΠ΅ ΠΎΡ ΡΠ°Π·ΠΈ Π²Π³ΡΠ°Π΄Π΅Π½Π° ΡΡΠ½ΠΊΡΠΈΡ. ΠΡΠΏΡΠ΅ΠΊΠΈ ΡΠΎΠ²Π°, Π°ΠΊΠΎ Π°ΡΡ ΠΈΡΠ΅ΠΊΡΡΡΠ°ΡΠ° Π½Π° Π±Π΅ΠΊΠ΅Π½Π΄Π° Π²ΠΈ ΠΏΡΠ΅Π΄Π²ΠΈΠΆΠ΄Π° Π²Π·Π°ΠΈΠΌΠΎΠ΄Π΅ΠΉΡΡΠ²ΠΈΠ΅ ΡΡΠ΅Π· Π±ΡΠΎΠΊΠ΅Ρ Π½Π° ΡΡΠΎΠ±ΡΠ΅Π½ΠΈΡ (RabbitMQ, Kafka ΠΈ Ρ.Π½.), Π²ΡΠ΅ ΠΏΠ°ΠΊ ΡΠ΅ ΡΡΡΠ±Π²Π° ΡΠ°ΠΌΠΈ Π΄Π° ΡΠ΅ ΠΏΠΎΠ³ΡΠΈΠΆΠΈΡΠ΅ Π·Π° ΠΏΡΠ΅Π΄Π°Π²Π°Π½Π΅ΡΠΎ Π½Π° ΠΊΠΎΡΠ΅Π»Π°ΡΠΈΠΎΠ½Π½ΠΈΡ ΠΊΠΎΠ½ΡΠ΅ΠΊΡΡ ΠΏΡΠ΅Π· ΡΠ΅Π·ΠΈ ΡΡΠΎΠ±ΡΠ΅Π½ΠΈΡ.
Π ΡΠ°Π·ΠΈ ΡΡΠ°ΡΠΈΡ ΡΠ΅ Π²Π·Π΅ΠΌΠ΅ΠΌ ΠΏΡΠΎΡΡΠΎ ΡΠ΅Π± API ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ ΠΈ ΡΠ΅ ΠΎΡΠ³Π°Π½ΠΈΠ·ΠΈΡΠ°ΠΌΠ΅ Π»ΠΎΠ³Π²Π°Π½Π΅, ΠΊΠΎΠ΅ΡΠΎ ΡΠ΅
Π·Π°ΠΏΠ°Π·Π²Π° ΡΠΊΠ²ΠΎΠ·Π½Π°ΡΠ° ΠΊΠΎΡΠ΅Π»Π°ΡΠΈΡ ΠΌΠ΅ΠΆΠ΄Ρ Π»ΠΎΠ³ΠΎΠ²Π΅ΡΠ΅ Π½Π° Π½Π΅Π·Π°Π²ΠΈΡΠΈΠΌΠΈΡΠ΅ ΡΡΠ»ΡΠ³ΠΈ, ΡΠ°ΠΊΠ° ΡΠ΅ Π΄Π° ΠΌΠΎΠΆΠ΅ΡΠ΅ Π»Π΅ΡΠ½ΠΎ Π΄Π° Π²ΠΈΠ΄ΠΈΡΠ΅ Π²ΡΠΈΡΠΊΠΈ Π°ΠΊΡΠΈΠ²Π½ΠΎΡΡΠΈ, ΠΊΠΎΠΈΡΠΎ ΡΠ° Π±ΠΈΠ»ΠΈ ΠΏΡΠ΅Π΄ΠΈΠ·Π²ΠΈΠΊΠ°Π½ΠΈ ΠΎΡ ΠΊΠΎΠ½ΠΊΡΠ΅ΡΠ½Π° Π·Π°ΡΠ²ΠΊΠ° ΠΎΡ ΠΊΠ»ΠΈΠ΅Π½ΡΠ°.
Π΄Π° ΠΈΠΌΠ°ΡΠ΅ Π΅Π΄ΠΈΠ½Π½Π° ΡΠΎΡΠΊΠ° Π½Π° Π²Ρ ΠΎΠ΄ Ρ ΡΠ΄ΠΎΠ±Π΅Π½ Π°Π½Π°Π»ΠΈΠ·, ΡΠ°ΠΊΠ° ΡΠ΅ ΠΈΠ½ΡΡΡΡΠΌΠ΅Π½ΡΡΡ Π·Π° Π»ΠΎΠ³Π²Π°Π½Π΅ Π΄Π° ΠΌΠΎΠΆΠ΅ Π΄Π° ΡΠ΅ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π° Π΄ΠΎΡΠΈ ΠΎΡ ΠΠΎΠ΄Π΄ΡΡΠΆΠΊΠ°ΡΠ°, ΠΊΠΎΡΡΠΎ ΠΏΠΎΠ»ΡΡΠ°Π²Π° Π²ΡΠΏΡΠΎΡΠΈ ΠΊΠ°ΡΠΎ "Π² ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ΡΠΎ ΠΌΠΈ Π΅ ΠΈΠ·ΡΠΊΠΎΡΠΈΠ»Π° Π³ΡΠ΅ΡΠΊΠ° Ρ ΡΠ°ΠΊΡΠ²-ΡΠΎ ΠΈΠ΄Π΅Π½ΡΠΈΡΠΈΠΊΠ°ΡΠΎΡ Π½Π° Π·Π°ΡΠ²ΠΊΠ°".
ΠΡΡΠ²ΠΎ, ΡΡΡΠ±Π²Π° Π΄Π° ΡΠ΅ ΠΎΠΏΡΠ΅Π΄Π΅Π»ΠΈΠΌ Ρ Π΄ΠΎΡΡΠ°Π²ΡΠΈΠΊΠ° Π½Π° Π»ΠΎΠ³Π²Π°Π½Π΅ Π² ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ΡΠΎ Π½ΠΈ. ΠΡΠ½ΠΎΠ²Π½ΠΎΡΠΎ ΠΈΠ·ΠΈΡΠΊΠ²Π°Π½Π΅ Π·Π° ΡΡΠ²ΡΠ΅ΠΌΠ΅Π½Π½ΠΎΡΠΎ Π»ΠΎΠ³Π²Π°Π½Π΅ Π΅ ΡΡΡΡΠΊΡΡΡΠ½ΠΎΡΡΡΠ°, Ρ.Π΅. ΡΡΡΠ±Π²Π° Π΄Π° ΡΠ°Π±ΠΎΡΠΈΠΌ Π½Π΅ Ρ ΠΏΠ»ΠΎΡΠΊΠΈ ΡΠ΅ΠΊΡΡΠΎΠ²ΠΈ ΡΡΠΎΠ±ΡΠ΅Π½ΠΈΡ, Π° Ρ ΠΎΠ±Π΅ΠΊΡΠΈ. Π‘ ΡΠ°ΠΊΠΈΠ²Π° Π»ΠΎΠ³ΠΎΠ²Π΅ Π»Π΅ΡΠ½ΠΎ ΠΌΠΎΠΆΠ΅ΠΌ Π΄Π° ΠΈΠ·Π³ΡΠ°Π΄ΠΈΠΌ ΠΏΡΠ΅Π΄ΡΡΠ°Π²Π»Π΅Π½ΠΈΡ Π½Π° ΡΡΠΎΠ±ΡΠ΅Π½ΠΈΡΡΠ° Π½ΠΈ ΠΎΡ ΡΠ°Π·Π»ΠΈΡΠ½ΠΈ ΡΠ³Π»ΠΈ ΠΈ Π΄Π° ΠΏΡΠΎΠ²Π΅ΠΆΠ΄Π°ΠΌΠ΅ Π°Π½Π°Π»ΠΈΠ·.
ΠΠ° Π½Π°ΡΠ΅ΡΠΎ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ ΡΠ΅ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°ΠΌΠ΅ ΠΏΠ°ΠΊΠ΅ΡΠ° Serilog, ΠΊΠΎΠΉΡΠΎ ΠΈΠΌΠ° ΠΎΡΠ»ΠΈΡΠ½Π° ΠΏΠΎΠ΄Π΄ΡΡΠΆΠΊΠ° Π·Π° ΡΡΡΡΠΊΡΡΡΠ½ΠΎ Π»ΠΎΠ³Π²Π°Π½Π΅ ΠΈ Π±ΠΎΠ³Π°ΡΠ° ΡΠΈΡΡΠ΅ΠΌΠ° ΠΎΡ Π΄ΠΎΠ±Π°Π²ΠΊΠΈ. Π©Π΅ ΠΏΡΠΎΠΏΡΡΠ½Π° ΠΎΡΠ½ΠΎΠ²Π½ΠΈΡΠ΅ ΡΡΡΠΏΠΊΠΈ Π·Π° Π½Π°ΡΡΡΠΎΠΉΠΊΠ° (ΠΌΠΎΠΆΠ΅ΡΠ΅ Π΄Π° Π½Π°ΠΌΠ΅ΡΠΈΡΠ΅ ΠΌΠ½ΠΎΠ³ΠΎ ΡΡΠ°ΡΠΈΠΈ ΠΏΠΎ ΡΠ΅ΠΌΠ°ΡΠ°) ΠΈ ΡΠ΅ ΠΏΡΠ΅Π΄ΠΏΠΎΠ»ΠΎΠΆΠ°, ΡΠ΅
Serilog Π²Π΅ΡΠ΅ Π΅ ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠΈΡΠ°Π½ ΠΈ Π΅ Π»ΠΎΠ³Π΅Ρ ΠΏΠΎ ΠΏΠΎΠ΄ΡΠ°Π·Π±ΠΈΡΠ°Π½Π΅ Π½Π° Π²Π°ΡΠΈΡ Π΄ΠΎΡΡΠ°Π²ΡΠΈΠΊ Π·Π° Π²Π½Π΅Π΄ΡΡΠ²Π°Π½Π΅ Π½Π° Π·Π°Π²ΠΈΡΠΈΠΌΠΎΡΡΠΈ.
Π² ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΡΡΠ° ΠΌΡ Π΅ Π²ΠΊΠ»ΡΡΠ΅Π½ΠΎ ΠΎΠ±ΠΎΠ³Π°ΡΡΠ²Π°Π½Π΅ Π½Π° ΡΡΠΎΠ±ΡΠ΅Π½ΠΈΡΡΠ° ΡΡΡ ΡΠ²ΠΎΠΉΡΡΠ²Π° ΠΎΡ ΠΊΠΎΠ½ΡΠ΅ΠΊΡΡΠ° (Enrich.FromLogContext).
Π‘Π»Π΅Π΄Π²Π°ΡΠ°ΡΠ° ΡΡΡΠΏΠΊΠ° Π΅ Π΄Π° ΠΈΠ·Π±Π΅ΡΠ΅ΠΌ Π² ΠΊΠΎΡ ΡΠΈΡΡΠ΅ΠΌΠ° Π·Π° ΡΠ΅Π½ΡΡΠ°Π»ΠΈΠ·ΠΈΡΠ°Π½ΠΎ ΡΡΠ±ΠΈΡΠ°Π½Π΅ Π½Π° Π»ΠΎΠ³ΠΎΠ²Π΅ Π΄Π° ΠΈΠ·ΠΏΡΠ°ΡΠ°ΠΌΠ΅ ΡΡΠΎΠ±ΡΠ΅Π½ΠΈΡ ΠΎΡ Serilog. ΠΠ°ΠΉ-ΡΠ°Π·ΠΏΡΠΎΡΡΡΠ°Π½Π΅Π½Π°ΡΠ° ΠΎΠΏΡΠΈΡ Π² ΠΌΠΎΠΌΠ΅Π½ΡΠ° ΡΡΠ΅Π΄ ΠΎΡΠ²ΠΎΡΠ΅Π½ΠΈΡΠ΅ ΡΠ΅ΡΠ΅Π½ΠΈΡ Π΅ ΡΡΠ΅ΠΊΠ° ELK (Elasticsearch, Logstash ΠΈ Kibana), ΠΈ ΡΠΎΡΠ½ΠΎ Π½Π΅Π³ΠΎ ΡΠ΅ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°ΠΌΠ΅. ΠΠ° ΡΠΎΠ²Π° ΡΠ΅ ΡΠ΅ Π²ΡΠ·ΠΏΠΎΠ»Π·Π²Π°ΠΌΠ΅ ΠΎΡ ΠΏΡΠ΅Π΄Π»ΠΎΠΆΠ΅Π½ΠΈΠ΅ΡΠΎ Π½Π° β ΡΠ»Π΅Π΄ ΡΠ΅Π³ΠΈΡΡΡΠ°ΡΠΈΡ Π½Π° Π±Π΅Π·ΠΏΠ»Π°ΡΠ½ΠΈΡ ΡΠ°ΡΠΈΡ ΠΈΠΌΠ°ΠΌΠ΅ Π½Π° ΡΠ°Π·ΠΏΠΎΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ ΡΡΠ»Π°ΡΠ° ΠΌΠΎΡ Π½Π° ΡΡΡΡΠ°ΡΠΊΠ°ΡΠ° Lucene.
ΠΡΡΠ°Π²Π° Π΄Π° Π΄ΠΎΠ±Π°Π²ΠΈΠΌ Π² Π½Π°ΡΠΈΡ ΠΏΡΠΎΠ΅ΠΊΡ ΠΏΠ°ΠΊΠ΅ΡΠ°
Install-Package Serilog.Sinks.Logzio
Π Π΄Π° Π΄ΠΎΠ±Π°Π²ΠΈΠΌ ΡΡΠΎΡΠ²Π΅ΡΠ½ΠΈΡ Π΅Π½ΡΠΈΡΠ΅Ρ Π² ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΡΡΠ° Π½Π° Π½Π°ΡΠΈΡ Π»ΠΎΠ³Π΅Ρ, Π·Π°Π΄Π°Π²Π°ΠΉΠΊΠΈ ΠΌΡ ΡΠΎΠΊΠ΅Π½Π° Π·Π° Π΄ΠΎΡΡΡΠΏ
LoggerConfiguration loggerConfig = new LoggerConfiguration();
loggerConfig.WriteTo.Logzio(secrets.LogzioToken, 10, TimeSpan.FromSeconds(10), null, LogEventLevel.Debug);
Π‘Π»Π΅Π΄ ΠΊΠ°ΡΠΎ ΡΡΠ°ΡΡΠΈΡΠ°ΠΌΠ΅ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ΡΠΎ, ΡΠ΅ ΠΌΠΎΠΆΠ΅ΠΌ Π΄Π° Π½Π°Π±Π»ΡΠ΄Π°Π²Π°ΠΌΠ΅ Π½Π°ΡΠΈΡΠ΅ ΡΡΠΎΠ±ΡΠ΅Π½ΠΈΡ Π½Π΅ ΡΠ°ΠΌΠΎ Π² ΠΊΠΎΠ½Π·ΠΎΠ»Π°ΡΠ°, Π½ΠΎ ΠΈ Π² ΠΠΈΠ±Π°Π½Π°.

ΠΠ½ΡΠ΅ΡΡΠ΅ΠΉΡΠΈ

Π ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ΡΠΎ ΠΎΡ ΡΠΈΠΏ ΡΡΠ»ΡΠ³Π° ΠΌΠΎΠΆΠ΅ΠΌ Π΄Π° ΠΎΡΠΊΡΠΎΠΈΠΌ Π΄Π²Π° ΠΎΡΠ½ΠΎΠ²Π½ΠΈ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡΠ° Π·Π° Π²Π·Π°ΠΈΠΌΠΎΠ΄Π΅ΠΉΡΡΠ²ΠΈΠ΅ Ρ Π²ΡΠ½ΡΠ½ΠΈΡ ΡΠ²ΡΡ, ΠΊΠΎΠΈΡΠΎ Π΄Π° Π½Π°ΡΠ΅ΡΠ΅ΠΌ Π²Π΅ΡΡΠΈΠΊΠ°Π»Π΅Π½ ΠΈ horizontal. ΠΠ΅ΡΡΠΈΠΊΠ°Π»Π½ΠΈΡΡ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡ Π΅ ΡΠ΅Π±-API, ΠΏΡΠ΅Π· ΠΊΠΎΠ΅ΡΠΎ ΠΈΠ΄Π²Π°Ρ ΠΏΠΎΠ²ΠΈΠΊΠ²Π°Π½ΠΈΡ ΠΎΡ ΠΊΠ»ΠΈΠ΅Π½ΡΡΠΊΠΎΡΠΎ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅. Π₯ΠΎΡΠΈΠ·ΠΎΠ½ΡΠ°Π»Π½ΠΈΡΡ Π΅ Π±ΡΠΎΠΊΠ΅Ρ Π½Π° ΡΡΠΎΠ±ΡΠ΅Π½ΠΈΡ, ΠΊΠΎΠΉΡΠΎ ΡΠ΅ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π° Π·Π° ΠΎΠ±ΠΌΠ΅Π½ Π½Π° Π΄Π°Π½Π½ΠΈ Ρ Π΄ΡΡΠ³ΠΈ Π²ΡΡΡΠ΅ΡΠ½ΠΈ ΡΡΠ»ΡΠ³ΠΈ.
ΠΠ΅ΠΊΠ° ΡΠ°Π·Π³Π»Π΅Π΄Π°ΠΌΠ΅ ΡΡΡΠΏΠΊΠΈΡΠ΅ Π·Π° Π²Π½Π΅Π΄ΡΡΠ²Π°Π½Π΅ Π½Π° ΠΊΠΎΡΠ΅Π»Π°ΡΠΈΡ Π½Π° Π²ΡΠ΅ΠΊΠΈ ΠΎΡ ΡΠ΅Π·ΠΈ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡΠΈ.
ΠΠΎΡΠ΅Π»Π°ΡΠΈΡ Π² HTTP Π·Π°ΡΠ²ΠΊΠΈΡΠ΅
ΠΠ° Π΄Π° ΠΏΠΎΠ»ΡΡΠ°Π²Π°ΠΌΠ΅ ΠΊΠΎΠ»ΠΊΠΎΡΠΎ Π΅ Π²ΡΠ·ΠΌΠΎΠΆΠ½ΠΎ ΠΏΠΎΠ²Π΅ΡΠ΅ ΠΈΠ½ΡΠΎΡΠΌΠ°ΡΠΈΡ, Π΅ Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΠΎ Π΄Π° Π³Π΅Π½Π΅ΡΠΈΡΠ°ΠΌΠ΅ ΠΈΠ΄Π΅Π½ΡΠΈΡΠΈΠΊΠ°ΡΠΎΡ Π½Π° ΠΊΠΎΡΠ΅Π»Π°ΡΠΈΡΡΠ° ΠΊΠΎΠ»ΠΊΠΎΡΠΎ ΡΠ΅ ΠΌΠΎΠΆΠ΅ ΠΏΠΎ-Π±Π»ΠΈΠ·ΠΎ Π΄ΠΎ Π½Π°ΡΠ°Π»ΠΎΡΠΎ Π½Π° Π°ΠΊΡΠΈΠ²Π½ΠΎΡΡΡΠ°, Ρ.Π΅. Π½Π° ΡΠ»ΡΠ·Π° ΠΈΠ»ΠΈ Π΄ΠΈΡΠ΅ΠΊΡΠ½ΠΎ Π½Π° ΠΊΠ»ΠΈΠ΅Π½ΡΠ° (ΠΌΠΎΠ±ΠΈΠ»Π΅Π½ ΠΈΠ»ΠΈ ΡΠ΅Π±). ΠΠΎΡΠΊΠΎΠ»ΡΠΊΡ Π΄Π½Π΅Ρ ΠΈΠΌΠ°ΠΌΠ΅ ΡΠ°Π±ΠΎΡΠ° Ρ Π±Π΅ΠΊΠ΅Π½Π΄ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅, ΠΏΡΠΎΡΡΠΎ ΡΠ΅ ΠΎΠ±ΠΎΠ·Π½Π°ΡΠΈΠΌ ΠΈΠ·ΠΈΡΠΊΠ²Π°Π½Π΅ΡΠΎ Π·Π° Π·Π°Π΄ΡΠ»ΠΆΠΈΡΠ΅Π»Π΅Π½ Π·Π°Π³Π»Π°Π²ΠΈΠ΅ΡΠΎ βX-Correlation-IDβ Π·Π° Π²ΡΠΈΡΠΊΠΈ Π·Π°ΡΠ²ΠΊΠΈ ΠΊΡΠΌ ΡΠ΅Π±-API.
ΠΠΎΠ±Π°Π²ΡΠΌΠ΅ ΠΏΠ°ΠΊΠ΅ΡΠ° , ΡΠΈΡΡΠΎ ΡΡΠ½ΠΊΡΠΈΡ Π΅ Π΄Π° ΠΈΠ·Π²Π»ΠΈΡΠ° ΡΡΠΎΠΉΠ½ΠΎΡΡΡΠ° ΠΎΡ Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΠΎΡΠΎ Π·Π°Π³Π»Π°Π²ΠΈΠ΅
Install-Package CorrelationID
ΠΠΎΠ±Π°Π²ΡΠΌΠ΅ Π³ΠΎ Π² ΠΊΠΎΠ½Π²Π΅ΠΉΠ΅ΡΠ° Π·Π° ΠΎΠ±ΡΠ°Π±ΠΎΡΠΊΠ° Π½Π° Π·Π°ΡΠ²ΠΊΠΈΡΠ΅
public class Startup
{
public void Configure(IApplicationBuilder application)
{
application
.UseCorrelationId(new CorrelationIdOptions
{
Header = "X-Correlation-ID",
IncludeInResponse = false,
UpdateTraceIdentifier = false,
UseGuidForCorrelationId = false
});
}
}
Π‘Π΅Π³Π° Ρ Π½Π΅Π³ΠΎΠ²Π°ΡΠ° ΠΏΠΎΠΌΠΎΡ ΡΠ΅ ΡΡΠ·Π΄Π°Π΄Π΅ΠΌ ΠΏΡΠΎΡΡ action-ΡΠΈΠ»ΡΡΡ:
ΠΏΡΠ±Π»ΠΈΡΠ΅Π½ Π·Π°ΠΏΠ΅ΡΠ°ΡΠ°Π½ ΠΊΠ»Π°Ρ ApiRequestFilter : ActionFilterAttribute
{
ΠΏΡΠ±Π»ΠΈΡΠ΅Π½ ApiRequestFilter(IApiRequestTracker apiRequestTracker, ICorrelationContextAccessor correlationContextAccessor)
{
_correlationContextAccessor = correlationContextAccessor ?? throw new ArgumentNullException(nameof(correlationContextAccessor));
}
ΡΠ°ΡΡΠ΅Π½ readonly ICorrelationContextAccessor _correlationContextAccessor;
ΠΏΡΠ±Π»ΠΈΡΠ΅Π½ override async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
{
if (!Guid.TryParse(_correlationContextAccessor.CorrelationContext.CorrelationId, out Guid correlationId))
{
context.Result = new BadRequestResult();
return;
}
await next.Invoke();
}
ΠΏΡΠ±Π»ΠΈΡΠ΅Π½ override async Task OnResultExecutionAsync(ResultExecutingContext context, ResultExecutionDelegate next)
{
await next.Invoke();
}
}
Π ΡΠ΅ Π³ΠΎ Π΄ΠΎΠ±Π°Π²ΠΈΠΌ Π² ΠΊΠΎΠ½ΡΡΠΎΠ»Π΅ΡΠ°
[Route("[controller]")]
[ApiController]
[ServiceFilter(typeof(ApiRequestFilter))]
ΠΏΡΠ±Π»ΠΈΡΠ΅Π½ ΠΊΠ»Π°Ρ CarsController : ControllerBase
{
}
Π ΡΠ΅Π·ΡΠ»ΡΠ°Ρ ΠΊΠΎΠ½ΡΡΠΎΠ»Π΅ΡΡΡ ΡΠ΅ ΠΈΠ·Π΄Π°Π²Π° 400 Bad Request Π½Π° Π²ΡΠΈΡΠΊΠΈ Π·Π°ΡΠ²ΠΊΠΈ Π±Π΅Π· Π·Π°Π³Π»Π°Π²ΠΊΠ° ΡΡΡ ΡΡΠΎΡΠ²Π΅ΡΠ½ΠΈΡ ΠΈΠ΄Π΅Π½ΡΠΈΡΠΈΠΊΠ°ΡΠΎΡ.
Π‘Π»Π΅Π΄ ΠΊΠ°ΡΠΎ Π·Π°ΠΏΠΎΡΠ½Π°Ρ ΠΌΠ΅ Π΄Π° ΠΏΠΎΠ»ΡΡΠ°Π²Π°ΠΌΠ΅ ΠΈΠ΄Π΅Π½ΡΠΈΡΠΈΠΊΠ°ΡΠΎΡ ΠΎΡ ΠΊΠ»ΠΈΠ΅Π½ΡΠ°, ΡΡΡΠ±Π²Π° Π΄Π° Π³ΠΎ Π΄ΠΎΠ±Π°Π²ΠΈΠΌ Π² ΠΊΠΎΠ½ΡΠ΅ΠΊΡΡΠ° Π½Π° Π»ΠΎΠ³Π²Π°Π½Π΅ΡΠΎ, ΡΠ΅ ΡΡΠ·Π΄Π°Π΄Π΅ΠΌ ΠΎΠ±Π³ΡΡΡΠ°ΡΠ° ΠΏΡΠΎΡΠ»ΠΎΠΉΠΊΠ° Π·Π° ΡΠ΅Π»ΡΠ°:
ΠΏΡΠ±Π»ΠΈΡΠ΅Π½ ΠΊΠ»Π°Ρ CorrelationIdContextLogger
{
ΠΏΡΠ±Π»ΠΈΡΠ΅Π½ CorrelationIdContextLogger(RequestDelegate next)
{
_next = next ?? throw new ArgumentNullException(nameof(next));
}
readonly RequestDelegate _next;
ΠΏΡΠ±Π»ΠΈΡΠ΅Π½ async Task InvokeAsync(HttpContext httpContext, ILogger logger, ICorrelationContextAccessor correlationContextAccessor)
{
if (Guid.TryParse(correlationContextAccessor.CorrelationContext.CorrelationId, out Guid correlationId))
{
using (logger.BeginScopeWith(("CorrelationId", correlationId)))
{
await _next(context);
}
}
else
{
await _next(context);
}
}
}
Π Π½Π°ΡΠ΅ΡΠΎ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°ΠΌΠ΅ ΡΡΠ°Π½Π΄Π°ΡΡΠ½ΠΈΡ ILogger ΠΎΡ ΠΏΠ°ΠΊΠ΅ΡΠ° Microsoft.Extensions.Logging.Abstractions, Π·Π°ΡΠΎΠ²Π° ΡΡΠΎΠΉΠ½ΠΎΡΡΡΠ° ΡΠ΅ Π΄ΠΎΠ±Π°Π²ΡΠΌΠ΅ Ρ ΠΏΡΠΎΡΡo ΡΠ°Π·ΡΠΈΡΠ΅Π½ΠΈΠ΅ ΠΊΡΠΌ Π½Π΅Π³ΠΎ.
ΠΏΡΠ±Π»ΠΈΡΠ΅Π½ static IDisposable BeginScopeWith(this ILogger logger, params (string key, object value)[] keys)
{
return logger.BeginScope(keys.ToDictionary(x => x.key, x => x.value));
}
ΠΠΎΠ±Π°Π²ΡΠΌΠ΅ ΠΏΡΠΎΡΠ»ΠΎΠΉΠΊΠ° Π² ΠΊΠΎΠ½Π²Π΅ΠΉΠ΅ΡΠ° Π·Π° ΠΎΠ±ΡΠ°Π±ΠΎΡΠΊΠ° Π½Π° Π·Π°ΡΠ²ΠΊΠΈ ΠΈ ΠΏΠΎΠ»ΡΡΠ°Π²Π°ΠΌΠ΅ ΠΆΠ΅Π»Π°Π½ΠΈΡ ΡΠ΅Π·ΡΠ»ΡΠ°Ρ.
ΠΏΡΠ±Π»ΠΈΡΠ΅Π½ ΠΊΠ»Π°Ρ Startup
{
ΠΏΡΠ±Π»ΠΈΡΠ΅Π½ void Configure(IApplicationBuilder application)
{
application.UseMiddleware();
}
}
Π‘Π΅Π³Π° Π²ΡΠΈΡΠΊΠΈ Π°ΠΊΡΠΈΠ²Π½ΠΎΡΡΠΈ, ΠΏΡΠΎΠΈΠ·ΡΠΈΡΠ°ΡΠΈ ΠΎΡ Π·Π°ΡΠ²ΠΊΠΈΡΠ΅ ΠΊΡΠΌ Π½Π°ΡΠ΅ΡΠΎ ΡΠ΅Π± API, ΡΡΠ΄ΡΡΠΆΠ°Ρ ΠΊΠΎΡΠ΅Π»Π°ΡΠΈΠΎΠ½Π΅Π½ ΠΈΠ΄Π΅Π½ΡΠΈΡΠΈΠΊΠ°ΡΠΎΡ, ΠΏΠΎ ΠΊΠΎΠΉΡΠΎ Π»Π΅ΡΠ½ΠΎ ΠΌΠΎΠ³Π°Ρ Π΄Π° Π±ΡΠ΄Π°Ρ ΡΠ²ΡΡΠ·Π°Π½ΠΈ.

ΠΠΎΡΠ΅Π»Π°ΡΠΈΡ Π² ΡΡΠΎΠ±ΡΠ΅Π½ΠΈΡΡΠ° Π½Π° Π±ΡΠΎΠΊΠ΅ΡΠ°
Π‘Π»Π΅Π΄Π²Π°ΡΠ°ΡΠ° ΡΡΡΠΏΠΊΠ° Π΅ Π΄Π° Π½Π°ΡΡΡΠΎΠΈΠΌ ΠΏΡΠ΅Π΄Π°Π²Π°Π½Π΅ΡΠΎ ΠΈ ΠΏΠΎΠ»ΡΡΠ°Π²Π°Π½Π΅ΡΠΎ Π½Π° ΠΊΠΎΡΠ΅Π»Π°ΡΠΈΠΎΠ½Π½ΠΈΡ ΠΈΠ΄Π΅Π½ΡΠΈΡΠΈΠΊΠ°ΡΠΎΡ ΡΡΠ΅Π· Π±ΡΠΎΠΊΠ΅Ρ Π½Π° ΡΡΠΎΠ±ΡΠ΅Π½ΠΈΡ. Π Π½Π°ΡΠΈΡ ΠΏΡΠΈΠΌΠ΅Ρ ΡΠ΅ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°ΠΌΠ΅ RabbitMQ, Π° Π·Π° ΠΊΠ»ΠΈΠ΅Π½Ρ ΡΠ΅ Π²Π·Π΅ΠΌΠ΅ΠΌ ΡΡΠ΅ΠΉΠΌΠ²ΠΎΡΠΊΠ° MassTransit. ΠΡΠ½ΠΎΠ²ΠΎ, ΡΠ΅ ΠΏΡΠΎΠΏΡΡΠ½Π΅ΠΌ Π½Π°ΡΠ°Π»Π½Π°ΡΠ° ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΡ Π·Π° ΡΠ°Π±ΠΎΡΠ° Ρ MassTransit ΠΈ ΡΠ΅ ΠΏΡΠ΅ΠΌΠΈΠ½Π΅ΠΌ Π½Π°ΠΏΡΠ°Π²ΠΎ ΠΊΡΠΌ Π½Π°ΡΡΡΠΎΠΉΠΊΠΈΡΠ΅ Π·Π° Π»ΠΎΠ³Π²Π°Π½Π΅.
ΠΠ° Π½Π°ΡΠ°Π»ΠΎ ΠΌΠΎΠΆΠ΅ΠΌ Π΄Π° Π°ΠΊΡΠΈΠ²ΠΈΡΠ°ΠΌΠ΅ Π»ΠΎΠ³ΠΎΠ²Π΅ΡΠ΅ Π½Π° ΡΠ°ΠΌΠΈΡ MassTransit, Π·Π° ΡΠ°Π·ΠΈ ΡΠ΅Π» Π΄ΠΎΠ±Π°Π²ΡΠΌΠ΅ Π² ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ΡΠΎ Π½ΠΈ ΠΏΠ°ΠΊΠ΅ΡΠ°
Install-Package MassTransit.SerilogIntegration
Π‘Π΅Π³Π° ΡΠ»Π΅Π΄ Π΄ΠΎΠ±Π°Π²ΡΠ½Π΅ΡΠΎ Π½Π° Π»ΠΎΠ³Π΅ΡΠ° Π² Π½Π°ΡΡΡΠΎΠΉΠΊΠΈΡΠ΅ Π½Π° MassTransit ΡΠ΅ ΠΌΠΎΠΆΠ΅ΠΌ Π΄Π° Π²ΠΈΠΆΠ΄Π°ΠΌΠ΅ Π»ΠΎΠ³ΠΎΠ²Π΅ΡΠ΅ Π½Π° ΡΡΠ΅ΠΉΠΌΠ²ΠΎΡΠΊΠ°.
services
.AddSingleton(provider =>
{
return Bus.Factory.CreateUsingRabbitMq(cfg =>
{
cfg.UseSerilog();
});
});
ΠΠ΅ΠΊΠ° Π½Π°ΡΠ΅ΡΠΎ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ Π΄Π° ΠΈΠ·ΠΏΡΠ°ΡΠ° ΡΡΠ±ΠΈΡΠΈΠ΅ SomethingDoneMessage ΡΡΡ ΡΡΠΎΠΉΠ½ΠΎΡΡ βdoneβ Π² ΠΎΡΠ³ΠΎΠ²ΠΎΡ Π½Π° POST Π·Π°ΡΠ²ΠΊΠ°. ΠΠΎΠ½ΡΡΠ°ΠΊΡΡΡ Π½Π° ΡΠ°ΠΊΠΎΠ²Π° ΡΡΠΎΠ±ΡΠ΅Π½ΠΈΠ΅ ΠΌΠΎΠΆΠ΅ Π΄Π° Π±ΡΠ΄Π΅ ΠΎΠΏΠΈΡΠ°Π½ ΡΠ°ΠΊΠ°:
namespace MbMessages
{
public interface ISomethingDoneMessageV1
{
string Value { get; }
}
}
Π‘ΡΠΎΠ±ΡΠ΅Π½ΠΈΡΡΠ° Π½Π° MassTransit Π²ΡΡΡΠ½ΠΎΡΡ ΠΏΡΠ΅Π΄ΡΡΠ°Π²Π»ΡΠ²Π°Ρ ΠΏΠ»ΠΈΠΊ, Π² ΠΊΠΎΠΉΡΠΎ ΡΠ° Π²Π»ΠΎΠΆΠ΅Π½ΠΈ ΡΡΠΎΠ±ΡΠ΅Π½ΠΈΡΡΠ° Π½Π° Π±ΡΠΎΠΊΠ΅ΡΠ°. ΠΠ»ΠΈΠΊΡΡ ΠΈΠ·Π³Π»Π΅ΠΆΠ΄Π° ΠΏΡΠΈΠ±Π»ΠΈΠ·ΠΈΡΠ΅Π»Π½ΠΎ ΡΠ°ΠΊΠ°:
{
"messageId": "59020000-5dba-0015-10b8-08d77ec28593",
"requestId": "59020000-5dba-0015-5674-08d77ec28592",
"conversationId": "59020000-5dba-0015-bca8-08d77ec28594",
"destinationAddress": "rabbitmq://bear.rmq.cloudamqp.com/aelzlsta/ya.servicetemplate.receiveendpoint",
"headers": {},
"messageType": [
"urn:message:MbMessages:ISomethingDoneMessageV1"
],
"message": {
"value": "done"
}
}
Π ΡΡΠΎΠ±ΡΠ΅Π½ΠΈΠ΅ΡΠΎ ΡΠ΅ Π²ΠΈΠΆΠ΄Π°Ρ ΡΠ»ΡΠΆΠ΅Π±Π½ΠΈΡΠ΅ ΠΏΠΎΠ»Π΅ΡΠ°, ΠΊΠΎΠΈΡΠΎ ΡΠ° Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΠΈ Π·Π° ΡΡΠ½ΠΊΡΠΈΠΎΠ½ΠΈΡΠ°Π½Π΅ΡΠΎ Π½Π° ΡΠ°ΠΌΠΈΡ ΡΡΠ΅ΠΉΠΌΠ²ΠΎΡΠΊ, Π½ΠΎ ΠΈΠΌΠ°ΠΌΠ΅ Π²ΡΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ Π΄Π° Π΄ΠΎΠ±Π°Π²ΡΠΌΠ΅ ΠΈ Π½Π°ΡΠΈ ΡΠΎΠ±ΡΡΠ²Π΅Π½ΠΈ Π΄ΠΎΠΏΡΠ»Π½ΠΈΡΠ΅Π»Π½ΠΈ ΡΠ²ΠΎΠΉΡΡΠ²Π°. ΠΡΠ²Π΅Π½ ΡΠΎΠ²Π°, MassTransit ΡΠ°Π·ΠΏΠΎΠ»Π°Π³Π° Ρ Π²Π³ΡΠ°Π΄Π΅Π½ΠΈ ΡΡΠ΅Π΄ΡΡΠ²Π° Π·Π° ΡΠ°Π±ΠΎΡΠ° Ρ Π½ΡΠΊΠΎΠΈ ΠΎΠΏΡΠΈΠΎΠ½Π°Π»Π½ΠΈ ΠΏΠΎΠ»Π΅ΡΠ°, ΠΎΡ ΠΊΠΎΠΈΡΠΎ Π½Π°ΠΉ-ΠΈΠ½ΡΠ΅ΡΠ΅ΡΠ½ΠΎ Π·Π° Π½Π°Ρ Π΅ ΠΈΠ΄Π΅Π½ΡΠΈΡΠΈΠΊΠ°ΡΠΎΡΡΡ Π½Π° ΠΊΠΎΡΠ΅Π»Π°ΡΠΈΠΎΠ½Π½ΠΎΡΡ CorrelationId.
ΠΠΎΠ±Π°Π²ΡΠΌΠ΅ ΠΊΡΠΌ Π΄ΠΎΠ³ΠΎΠ²ΠΎΡΠ° Π½Π° ΡΡΠΎΠ±ΡΠ΅Π½ΠΈΠ΅ΡΠΎ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡΠ° CorrelatedBy:
namespace MbMessages
{
public interface ISomethingDoneMessageV1 : CorrelatedBy
{
string Value { get; }
}
}
Π Π΅Π°Π»ΠΈΠ·ΠΈΡΠ°ΠΌΠ΅ Π³ΠΎ ΠΈ ΡΠ΅ Π·Π°Π΄Π°Π²Π°ΠΌΠ΅ ΡΡΠΎΠΉΠ½ΠΎΡΡ Π½Π° ΡΠ²ΠΎΠΉΡΡΠ²ΠΎΡΠΎ CorrelationId ΠΏΡΠΈ ΡΡΠ·Π΄Π°Π²Π°Π½Π΅ΡΠΎ Π½Π° ΡΡΠΎΠ±ΡΠ΅Π½ΠΈΠ΅:
internal class SomethingDoneMessageV1 : ISomethingDoneMessageV1
{
internal SomethingDoneMessageV1(Guid correlationId, string value)
{
CorrelationId = correlationId;
Value = value;
}
public Guid CorrelationId { get; private set; }
public string Value { get; private set; }
}
ΠΠΎΠ³Π°ΡΠΎ ΡΠ°Π·Π³Π»Π΅Π΄Π°ΠΌΠ΅ ΠΎΠ±Π½ΠΎΠ²Π΅Π½ΠΎΡΠΎ ΡΡΠΎΠ±ΡΠ΅Π½ΠΈΠ΅, ΡΠ΅ Π²ΠΈΠ΄ΠΈΠΌ, ΡΠ΅ ΠΈΠ΄Π΅Π½ΡΠΈΡΠΈΠΊΠ°ΡΠΎΡΡΡ Π½Π° ΠΊΠΎΡΠ΅Π»Π°ΡΠΈΡΡΠ° Π΅ ΡΡΠ°Π½Π°Π» Π½Π΅ ΡΠ°ΠΌΠΎ ΡΠ°ΡΡ ΠΎΡ Π½Π°ΡΠ΅ΡΠΎ ΡΡΠΎΠ±ΡΠ΅Π½ΠΈΠ΅, Π½ΠΎ ΠΈ ΡΠ°ΡΡ ΠΎΡ ΠΊΠΎΠ½Π²Π΅ΡΡΠ° β ΡΠΎΠ·ΠΈ ΠΈΠ΄Π΅Π½ΡΠΈΡΠΈΠΊΠ°ΡΠΎΡ ΡΠ΅Π³Π° ΡΠ΅ ΡΠ΅ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π° ΠΈ Π²ΡΠ² Π²ΡΠΈΡΠΊΠΈ Π»ΠΎΠ³ΠΎΠ²Π΅ Π½Π° MassTransit, ΠΊΠΎΠ΅ΡΠΎ ΡΠ΅ ΡΠ»Π΅ΡΠ½ΠΈ ΡΠ°Π·Π±ΠΈΡΠ°Π½Π΅ΡΠΎ Π½Π° ΠΏΡΠΎΠ±Π»Π΅ΠΌΠΈΡΠ΅ Π½Π° Π½ΠΈΠ²ΠΎ Π±ΡΠΎΠΊΠ΅Ρ Π½Π° ΡΡΠΎΠ±ΡΠ΅Π½ΠΈΡ.
{
"messageId": "59020000-5dba-0015-10b8-08d77ec28593",
"requestId": "59020000-5dba-0015-5674-08d77ec28592",
"conversationId": "59020000-5dba-0015-bca8-08d77ec28594",
"correlationId": "c7ff562a-b639-415b-9add-c9e524a727cc",
"destinationAddress": "rabbitmq://bear.rmq.cloudamqp.com/aelzlsta/ya.servicetemplate.receiveendpoint",
"headers": {},
"messageType": [
"urn:message:MbMessages:ISomethingDoneMessageV1"
],
"message": {
"correlationId": "c7ff562a-b639-415b-9add-c9e524a727cc",
"value": "Hello"
}
}
ΠΡΡΡΠ°Π½ΡΠ²Π°ΠΌΠ΅ ΡΠ°ΠΌΠΎ Π΄Π° ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠΈΡΠ°ΠΌΠ΅ Π»ΠΎΠ³Π²Π°Π½Π΅ΡΠΎ Π½Π° ΡΠ΅Π·ΠΈ ΡΠ»ΡΠΆΠ΅Π±Π½ΠΈ ΡΠ²ΠΎΠΉΡΡΠ²Π° Π½Π° ΡΡΠΎΠ±ΡΠ΅Π½ΠΈΠ΅ΡΠΎ, ΠΊΠ°ΡΠΎ Π΄ΠΎΠ±Π°Π²ΠΈΠΌ ΠΏΠ°ΠΊΠ΅Ρ Π² ΠΏΡΠΎΠ΅ΠΊΡΠ° . ΠΠ°ΠΊΠ΅ΡΡΡ Π΄ΠΎΠ±Π°Π²Ρ ΡΠΈΠ»ΡΡΡ Π² ΠΊΠΎΠ½Π²Π΅ΠΉΠ΅ΡΠ° Π½Π° MassTransit, ΠΊΠΎΠΉΡΠΎ ΠΏΠΎΡΡΠ°Π²Ρ ΠΊΠΎΠ½ΡΠ΅ΠΊΡΡΠ° Π½Π° ΡΡΠΎΠ±ΡΠ΅Π½ΠΈΠ΅ΡΠΎ Π² ΠΏΠΎΡΠΎΠΊΠΎΠ±Π΅Π·ΠΎΠΏΠ°ΡΠ΅Π½ ΡΡΠ΅ΠΊ. Serilog ΡΠ΅ΡΠ΅ ΠΊΠΎΠ½ΡΠ΅ΠΊΡΡΠ° ΠΎΡ ΡΡΠ΅ΠΊΠ° ΠΈ Π΄ΠΎΠ±Π°Π²Ρ ΡΠ΅Π·ΠΈ Π΄ΠΎΠΏΡΠ»Π½ΠΈΡΠ΅Π»Π½ΠΈ ΡΠ²ΠΎΠΉΡΡΠ²Π° Π² Π½Π°ΡΠΈΡΠ΅ Π»ΠΎΠ³ΠΎΠ²Π΅.
Install-Package Serilog.Enrichers.MassTransitMessage
Π MassTransit Π΄ΠΎΠ±Π°Π²ΡΠΌΠ΅ ΡΠΈΠ»ΡΡΡ
services
.AddSingleton(provider =>
{
return Bus.Factory.CreateUsingRabbitMq(cfg =>
{
cfg.UseSerilog();
cfg.UseSerilogMessagePropertiesEnricher();
});
});
Π Π² ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΡΡΠ° Π½Π° Serilog Π΄ΠΎΠ±Π°Π²ΡΠΌΠ΅ Π΅Π½ΡΠΈΡΠ΅Ρ
Log.Logger = new LoggerConfiguration()
.Enrich.FromMassTransitMessage()
.CreateLogger();
Π’ΡΠΉ ΠΊΠ°ΡΠΎ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ΡΠΎ, ΠΊΠΎΠ΅ΡΠΎ ΠΏΠΎΠ»ΡΡΠ°Π²Π° ΡΡΠΎΠ±ΡΠ΅Π½ΠΈΠ΅ ΠΎΡ ΠΎΠΏΠ°ΡΠΊΠ°ΡΠ° RabbitMQ, ΠΈΠΌΠ° Π΄ΠΎΡΡΡΠΏ Π΄ΠΎ Π²ΡΠΈΡΠΊΠΈ ΡΠ²ΠΎΠΉΡΡΠ²Π° Π½Π° ΠΊΠΎΠ½Π²Π΅ΡΡΠ° Π½Π° MassTransit, ΠΌΠΎΠΆΠ΅ΠΌ Π΄Π° ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°ΠΌΠ΅ ΠΏΠΎΠ»ΡΡΠ΅Π½ΠΈΡ ΠΈΠ΄Π΅Π½ΡΠΈΡΠΈΠΊΠ°ΡΠΎΡ Π½Π° ΠΊΠΎΡΠ΅Π»Π°ΡΠΈΡΡΠ° Π² ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ΡΠΎ Π½Π° ΠΏΠΎΡΡΠ΅Π±ΠΈΡΠ΅Π»Ρ ΠΈ ΡΡΡΠΎ ΡΠ°ΠΊΠ° Π΄Π° Π³ΠΎ ΠΏΡΠ΅Π΄Π°Π²Π°ΠΌΠ΅ ΠΏΠΎ ΡΡΠ»Π°ΡΠ° Π²Π΅ΡΠΈΠ³Π° ΠΎΡ ΠΏΠΎΠ²ΠΈΠΊΠ²Π°Π½ΠΈΡ.
Π ΡΠ΅Π·ΡΠ»ΡΠ°Ρ Π½Π° ΡΠΎΠ²Π° Π½Π°ΡΠΈΡΠ΅ Π»ΠΎΠ³ΠΎΠ²Π΅ ΡΡΠ΄ΡΡΠΆΠ°Ρ CorrelationId Π½Π΅ ΡΠ°ΠΌΠΎ Π² ΡΠ°ΠΌΠΊΠΈΡΠ΅ Π½Π° Π΅Π΄ΠΈΠ½ ΡΠ΅ΡΠ²ΠΈΡ, Π½ΠΎ ΠΈ ΠΏΡΠΈ Π²Π·Π°ΠΈΠΌΠΎΠ΄Π΅ΠΉΡΡΠ²ΠΈΠ΅ΡΠΎ Ρ Π΄ΡΡΠ³ΠΈ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ.

Π’Π°ΠΊΠ° ΠΏΠΎΠ»ΡΡΠ΅Π½Π°ΡΠ° ΡΠΈΡΡΠ΅ΠΌΠ° Π·Π° Π»ΠΎΠ³Π²Π°Π½Π΅ Π² .Net ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ ΠΏΠΎΠ·Π²ΠΎΠ»ΡΠ²Π° Π±Π΅Π· ΠΎΡΠΎΠ±Π΅Π½ΠΈ ΠΏΡΠΎΠ±Π»Π΅ΠΌΠΈ Π΄Π° ΠΊΠΎΡΠ΅Π»ΠΈΡΠ°ΠΌΠ΅ Π»ΠΎΠ³ΠΎΠ²Π΅ΡΠ΅ ΠΎΡ Π°Π±ΡΠΎΠ»ΡΡΠ½ΠΎ ΡΠ°Π·Π»ΠΈΡΠ½ΠΈ ΠΌΠΈΠΊΡΠΎΡΠ΅ΡΠ²ΠΈΠ·ΠΈ β Π΄ΠΎΡΠΈ ΠΈ ΡΠ΅Π·ΠΈ, ΠΊΠΎΠΈΡΠΎ ΡΠ°Π±ΠΎΡΡΡ ΡΡΠ΅Π· Π±ΡΠΎΠΊΠ΅Ρ Π½Π° ΡΡΠΎΠ±ΡΠ΅Π½ΠΈΡ. Π Ρ ΠΏΠΎΠΌΠΎΡΡΠ° Π½Π° Elasticsearch ΠΌΠΎΠΆΠ΅ΠΌ Π±ΡΡΠ·ΠΎ ΠΈ ΡΠ΄ΠΎΠ±Π½ΠΎ Π΄Π° ΠΈΠ·Π²ΡΡΡΠ²Π°ΠΌΠ΅ Π°Π½Π°Π»ΠΈΠ· Π½Π° Π»ΠΎΠ³ΠΎΠ²Π΅ΡΠ΅, ΠΊΠ°ΡΠΎ ΠΈΠ·Π³ΡΠ°Π΄ΠΈΠΌ Π² Kibana Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΠΈΡΠ΅ Π½ΠΈ ΡΠ°Π±Π»Π° Π·Π° ΡΠΏΡΠ°Π²Π»Π΅Π½ΠΈΠ΅ (ΠΏΡΠΈΠΌΠ΅ΡΡΡ Π΅ ΠΏΠΎΠΊΠ°Π·Π°Π½ Π½Π° ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΠ΅ΡΠΎ ΠΊΡΠΌ ΠΏΡΠ±Π»ΠΈΠΊΠ°ΡΠΈΡΡΠ°).
Π Π°Π·Π±ΠΈΡΠ° ΡΠ΅, Π² ΡΠΎΠ·ΠΈ Π²ΠΈΠ΄ Π»ΠΎΠ³Π²Π°Π½Π΅ΡΠΎ Π½Π΅ ΠΏΠΎΠΊΡΠΈΠ²Π° ΡΠ»ΠΎΠΆΠ½ΠΈΡΠ΅ Π²Π°ΡΠΈΠ°Π½ΡΠΈ Π·Π° Π²Π·Π°ΠΈΠΌΠΎΠ΄Π΅ΠΉΡΡΠ²ΠΈΠ΅ ΠΌΠ΅ΠΆΠ΄Ρ Π²Π°ΡΠΈΡΠ΅ ΡΡΠ»ΡΠ³ΠΈ ΠΈ ΡΠ°Π·Π»ΠΈΡΠ½ΠΈ Π²ΡΠ½ΡΠ½ΠΈ ΡΠΈΡΡΠ΅ΠΌΠΈ, Π½ΠΎ ΡΡΡΠ°Π½ΠΎΠ²ΡΠ²Π°Π½Π΅ΡΠΎ Π½Π° ΡΠ°ΠΊΡΠ² ΡΠ΅Π΄ Π² ΡΠ°ΠΌΠΎΡΠΎ Π½Π°ΡΠ°Π»ΠΎ Π½Π° ΡΠ°Π·Π²ΠΈΡΠΈΠ΅ΡΠΎ Π½Π° ΠΏΡΠΎΠ΅ΠΊΡΠ° Π΅ Π΅Π΄Π½Π° ΠΎΡ ΡΠ΅Π·ΠΈ Π½Π΅ΡΠ°, Π·Π° ΠΊΠΎΠΈΡΠΎ ΡΠ°ΠΌΠΈ ΡΠ΅ ΡΠΈ Π±Π»Π°Π³ΠΎΠ΄Π°ΡΠΈΡΠ΅.
ΠΠΎΠΆΠ΅ΡΠ΅ Π΄Π° ΡΠ°Π·Π³Π»Π΅Π΄Π°ΡΠ΅ ΠΈΠ·Ρ ΠΎΠ΄Π½ΠΈΡ ΠΊΠΎΠ΄ Π½Π° ΠΏΠΎΠ»ΡΡΠ΅Π½Π°ΡΠ° ΡΠΈΡΡΠ΅ΠΌΠ° Π² ΠΏΡΠΎΠ΅ΠΊΡΠ°:
ΠΠ·ΡΠΎΡΠ½ΠΈΠΊ: habr.com
