
ΠΠΎΠ³ΠΈΡΠ΅ Π΅ ΠΈΠ·ΠΊΠ»ΡΡΠΈΡΠ΅Π»Π½ΠΎ Π²Π°ΠΆΠ΅Π½ ΠΈΠ½ΡΡΡΡΠΌΠ΅Π½Ρ Π·Π° ΡΠ°Π·ΡΠ°Π±ΠΎΡΡΠΈΡΠΈΡΠ΅, Π½ΠΎ ΠΊΠΎΠ³Π°ΡΠΎ ΡΡΠ°Π²Π° Π²ΡΠΏΡΠΎΡ Π·Π° ΡΡΠ·Π΄Π°Π²Π°Π½Π΅ Π½Π° ΡΠ°Π·ΠΏΡΠ΅Π΄Π΅Π»Π΅Π½ΠΈ ΡΠΈΡΡΠ΅ΠΌΠΈ, ΡΠΎΠΉ ΡΡΠ°Π²Π° ΠΎΡΠ½ΠΎΠ²Π΅Π½ Π΅Π»Π΅ΠΌΠ΅Π½Ρ, ΠΊΠΎΠΉΡΠΎ ΡΡΡΠ±Π²Π° Π΄Π° Π±ΡΠ΄Π΅ Π·Π°Π»ΠΎΠΆΠ΅Π½ Π² ΠΎΡΠ½ΠΎΠ²Π°ΡΠ° Π½Π° Π²Π°ΡΠ΅ΡΠΎ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅, Π² ΠΏΡΠΎΡΠΈΠ²Π΅Π½ ΡΠ»ΡΡΠ°ΠΉ ΡΠ»ΠΎΠΆΠ½ΠΎΡΡΡΠ° Π½Π° ΡΠ°Π·ΡΠ°Π±ΠΎΡΠΊΠ°ΡΠ° Π½Π° ΠΌΠΈΠΊΡΠΎΡΠ΅ΡΠ²ΠΈΠ·ΠΈ Π±ΡΡΠ·ΠΎ ΡΠ΅ ΡΠ΅ ΠΏΡΠΎΡΠ²ΠΈ.
Π .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);
Π‘Π»Π΅Π΄ ΡΡΠ°ΡΡΠΈΡΠ°Π½Π΅ Π½Π° ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ΡΠΎ ΡΠ΅ ΠΌΠΎΠΆΠ΅ΠΌ Π΄Π° Π½Π°Π±Π»ΡΠ΄Π°Π²Π°ΠΌΠ΅ Π½Π°ΡΠΈΡΠ΅ ΡΡΠΎΠ±ΡΠ΅Π½ΠΈΡ Π½Π΅ ΡΠ°ΠΌΠΎ Π² ΠΊΠΎΠ½Π·ΠΎΠ»Π°ΡΠ°, Π½ΠΎ ΠΈ Π² Kibana.

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

Π ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ΡΠΎ ΠΎΡ ΡΠΈΠΏ ΡΡΠ»ΡΠ³Π° ΠΌΠΎΠΆΠ΅ΠΌ Π΄Π° ΠΎΡΠΊΡΠΎΠΈΠΌ Π΄Π²Π° ΠΎΡΠ½ΠΎΠ²Π½ΠΈ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡΠ° Π·Π° Π²Π·Π°ΠΈΠΌΠΎΠ΄Π΅ΠΉΡΡΠ²ΠΈΠ΅ Ρ Π²ΡΠ½ΡΠ½ΠΈΡ ΡΠ²ΡΡ, ΠΊΠΎΠΈΡΠΎ ΡΠ΅ ΠΎΠ±ΠΎΠ·Π½Π°ΡΠΈΠΌ ΠΊΠ°ΡΠΎ Π²Π΅ΡΡΠΈΠΊΠ°Π»Π΅Π½ ΠΈ Ρ ΠΎΡΠΈΠ·ΠΎΠ½ΡΠ°Π»Π΅Π½. ΠΠ΅ΡΡΠΈΠΊΠ°Π»Π½ΠΈΡΡ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡ Π΅ ΡΠ΅Π± 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 ?? Π²ΡΠ±ΡΠΎΡΠΈΡΡ Π½ΠΎΠ²ΠΎΠ΅ ArgumentNullException(nameof(correlationContextAccessor));
}
ΡΠ°ΡΡΠ½ΡΠΉ readonly ICorrelationContextAccessor _correlationContextAccessor;
ΠΏΡΠ±Π»ΠΈΡΠ½ΡΠΉ ΠΏΠ΅ΡΠ΅ΠΎΠΏΡΠ΅Π΄Π΅Π»ΡΠ΅ΠΌΡΠΉ async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
{
Π΅ΡΠ»ΠΈ (!Guid.TryParse(_correlationContextAccessor.CorrelationContext.CorrelationId, out Guid correlationId))
{
context.Result = Π½ΠΎΠ²Π°Ρ BadRequestResult();
Π²ΠΎΠ·Π²ΡΠ°Ρ;
}
await next.Invoke();
}
ΠΏΡΠ±Π»ΠΈΡΠ½ΡΠΉ ΠΏΠ΅ΡΠ΅ΠΎΠΏΡΠ΅Π΄Π΅Π»ΡΠ΅ΠΌΡΠΉ 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 ?? Π²ΡΠ±ΡΠΎΡΠΈΡΡ Π½ΠΎΠ²ΠΎΠ΅ ArgumentNullException(nameof(next));
}
readonly RequestDelegate _next;
ΠΏΡΠ±Π»ΠΈΡΠ½ΡΠΉ async Task InvokeAsync(HttpContext httpContext, ILogger logger, ICorrelationContextAccessor correlationContextAccessor)
{
Π΅ΡΠ»ΠΈ (Guid.TryParse(correlationContextAccessor.CorrelationContext.CorrelationId, out Guid correlationId))
{
ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΡ (logger.BeginScopeWith(("CorrelationId", correlationId)))
{
await _next(context);
}
}
Π΅ΡΠ΅
{
await _next(context);
}
}
}
Π Π½Π°ΡΠ΅ΠΌ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΈ ΠΌΡ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΠΌ ΡΡΠ°Π½Π΄Π°ΡΡΠ½ΡΠΉ ILogger ΠΈΠ· ΠΏΠ°ΠΊΠ΅ΡΠ° Microsoft.Extensions.Logging.Abstractions, ΠΏΠΎΡΡΠΎΠΌΡ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ Π±ΡΠ΄Π΅ΠΌ Π΄ΠΎΠ±Π°Π²Π»ΡΡΡ Ρ ΠΏΠΎΠΌΠΎΡΡΡ ΠΏΡΠΎΡΡΠΎΠ³ΠΎ ΡΠ°ΡΡΠΈΡΠ΅Π½ΠΈΡ ΠΊ Π½Π΅ΠΌΡ.
public static IDisposable BeginScopeWith(this ILogger logger, params (string key, object value)[] keys)
{
Π²ΠΎΠ·Π²ΡΠ°ΡΠ°Π΅Ρ 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();
});
});
ΠΠ΅ΠΊΠ° ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ΡΠΎ Π½ΠΈ ΠΊΠ°ΡΠΎ ΡΠ΅Π°ΠΊΡΠΈΡ Π½Π° POST Π·Π°ΡΠ²ΠΊΠ° Π΄Π° ΠΈΠ·ΠΏΡΠ°ΡΠ° ΡΡΠ±ΠΈΡΠΈΠ΅ SomethingDoneMessage ΡΡΡ ΡΡΠΎΠΉΠ½ΠΎΡΡ βdoneβ. ΠΠΎΠ½ΡΡΠ°ΠΊΡΡΡ Π½Π° ΡΠ°ΠΊΠΎΠ²Π° ΡΡΠΎΠ±ΡΠ΅Π½ΠΈΠ΅ ΠΌΠΎΠΆΠ΅ Π΄Π° ΡΠ΅ ΠΎΠΏΠΈΡΠ΅ ΡΠ°ΠΊΠ°:
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": "ΠΠ΄ΡΠ°Π²Π΅ΠΉ"
}
}
ΠΡΡΠ°Π²Π° Π½ΠΈ Π΄Π° Π½Π°ΡΡΡΠΎΠΈΠΌ ΡΠ΅Π³ΠΈΡΡΡΠΈΡΠ°Π½Π΅ΡΠΎ Π½Π° ΡΠ΅Π·ΠΈ ΡΠ»ΡΠΆΠ΅Π±Π½ΠΈ ΡΠ²ΠΎΠΉΡΡΠ²Π° Π½Π° ΡΡΠΎΠ±ΡΠ΅Π½ΠΈΠ΅ΡΠΎ, Π·Π° ΠΊΠΎΠ΅ΡΠΎ ΡΠ΅ Π΄ΠΎΠ±Π°Π²ΠΈΠΌ Π² ΠΏΡΠΎΠ΅ΠΊΡΠ° ΠΏΠ°ΠΊΠ΅ΡΠ° . ΠΠ°ΠΊΠ΅ΡΡΡ Π΄ΠΎΠ±Π°Π²Ρ ΡΠΈΠ»ΡΡΡ Π² ΠΊΠΎΠ½Π²Π΅ΠΉΠ΅ΡΠ° Π·Π° ΠΎΠ±ΡΠ°Π±ΠΎΡΠΊΠ° Π½Π° ΡΡΠΎΠ±ΡΠ΅Π½ΠΈΡ Π² 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
