From 75ef1ed69c063a98b42a4fb5c981d98984abdce5 Mon Sep 17 00:00:00 2001 From: Janusz Szczypka Date: Fri, 18 Sep 2026 14:40:44 +0000 Subject: [PATCH] Fix live log reads and timestamp service output --- README.md | 4 +- release-optima/SmartB2B.Optima.Adapter.dll | Bin 37376 -> 37376 bytes release-optima/SmartB2B.Optima.Adapter.pdb | Bin 15864 -> 15860 bytes release-optima/SmartB2B.Optima.Service.dll | Bin 22528 -> 22528 bytes release-optima/SmartB2B.Optima.Service.exe | Bin 121344 -> 121344 bytes release-optima/SmartB2B.Optima.Service.pdb | Bin 17924 -> 17928 bytes release-optima/SmartB2B.Sync.Contracts.dll | Bin 21504 -> 21504 bytes release-optima/SmartB2B.Sync.Contracts.pdb | Bin 14340 -> 14340 bytes release-optima/SmartB2B.Sync.Service.dll | Bin 55296 -> 57856 bytes release-optima/SmartB2B.Sync.Service.pdb | Bin 25364 -> 26192 bytes release-optima/daemon/smartb2bsync-optima.xml | 2 +- src/SmartB2B.Enova.Service/Program.cs | 1 + src/SmartB2B.Optima.Service/Program.cs | 1 + .../Diagnostics/ConsoleLogger.cs | 6 ++ .../Diagnostics/DiagnosticsHandler.cs | 13 ++- .../Diagnostics/TimestampedTextWriter.cs | 93 ++++++++++++++++++ tests/SmartB2B.Optima.Tests/Program.cs | 84 +++++++++++++++- 17 files changed, 198 insertions(+), 6 deletions(-) create mode 100644 src/SmartB2B.Sync.Service/Diagnostics/TimestampedTextWriter.cs diff --git a/README.md b/README.md index 39ef667..56ebd28 100644 --- a/README.md +++ b/README.md @@ -62,7 +62,9 @@ operatora: Szczegółowe logowanie włącza parametr `/debug` albo `/verbose` (obsługiwane są też warianty `--debug` i `--verbose`). Wyłącza je brak parametru lub jawny parametr `/nodebug` albo `/noverbose`. Błędy są zapisywane do `stderr` niezależnie od tego -ustawienia. W usłudze Windows parametr można włączyć przez odkomentowanie elementu +ustawienia. Każdy wiersz `stdout` i `stderr` zaczyna się znacznikiem czasu ISO 8601 +w UTC, np. `2026-09-18T12:34:56.7890000+00:00`. W usłudze Windows parametr można +włączyć przez odkomentowanie elementu `/verbose` w `daemon-enova/smartb2bsync-enova.xml` i restart usługi. W trybie szczegółowym zapis ZO raportuje kolejne etapy: walidację żądania, logowanie diff --git a/release-optima/SmartB2B.Optima.Adapter.dll b/release-optima/SmartB2B.Optima.Adapter.dll index f3d7e3eccb5fb10ff5e6398de36c31e8e190dbe6..3d9897ef3c4d0e574ad2b1bbea70d0569cdecc07 100644 GIT binary patch delta 234 zcmZoz!ql*YX+j4JqfYzNjXh_o1*9MMU0v!q(|P7Aqdkgy1p7B<)FkkzCnXuC8KsyS z8>FO~CL5-urlgrBnI$Ks7+IR9rkEvJCZ!pg8km_+e&12bqV{anoXHuT0Rqo80#s0^5-JE(En|5k{m0SpD{@dmmF6HKiD}p@3sHtjG6=G;`B5a}yJjv}Cii$?rQ#S*|r~dp0?vGeF=|uwvKB z^KV@@Cf{l2|LoB;`9x>80#q>75Gn{%otB^X?0V~xjl2G9eO$7+xa%j2uNgx!LlT22 zgE>PYLkfcl5F0Y2G8h0wjDXMrhz%Gl8O(q(i9mHJKyd@0Xc|zxDVQ_?%9sFI$v`z} Kn|JoRGXVf|UsV7A diff --git a/release-optima/SmartB2B.Optima.Adapter.pdb b/release-optima/SmartB2B.Optima.Adapter.pdb index 75b09926471d3d24ebb61735d5d3014bf91b82e8..881437c798e09e421316a1b43502ed74f3be9460 100644 GIT binary patch delta 1082 zcmexS{iS+Bfr5lF1B0?tPJR*t1H-eOU-@tPT=Cht?b1xWyZ4T(JzF(r;)H8*3$=lg z42%puIuINTq(L|ej3*m1DbzDEBp*-Dh+hJ6wJsCG2R$Z+a(yO- zjX=y}z{HRR#En4Q3B;=mK>C>(_82fTd;?-ZLuLkRAod61Tp;cR;`u=Q7>Hj1@kc`z zh95xe&uPTMkP5_IMnKmzPj+BpHD_X2XT-#?)d*xF6T@C8eFRK1Gn|3aH^4Lt!+oIU z4?z5V^J^w&)_P;0V?hpKU|<1aMur_aY(SbFh&jOgTLxS}nj46Dz4_0#LCYzx<6~%Ut-;I;?!J?-P_wg*eGS(D#I z@PG1O``?GvcB?KaQPy;+yL9(uas2(4QyRniw&$XfMJH7De?6A>RJ#7@ z!VQxWy5-6k6`~vxvP&-xvXtyqvpHX6sgl@g z#?_k`SD$5EeVuXjW5(5=8P~8du92RsWu7mCRjQ3~%}k(z&0EdcSR}Ej*l+?QeZ|_D O5v$poBqrM$|f1mXuk{2GXBb(t7G=`k@>>N7EH z24X$~CWag!ZU*9RAYNkt($CDW&w!cX2M`MzGBel$aUc-q193kPF9hPJK>P-XKO3?z z`~u=YP9qkEbRh0A0=lMovI7&VITOPMBPNFJMj#WJ81_TyV_=$@;T)8{1*TaT9s)Ig z0^*;WUo$zg)|&zy3vvhp0}Bu{GVIb}1Jdk3%mL=#G2jBy+(66&=35x?0cn09764*( z23Ce9R&@q8hJWk{U|r2Xa~fE;0Zly2cnwHSW4Zw}se$zykiCc5f(gW)0Va2VND0;( zK4_0q$l!Erc4o-a&|ha`|K^YIZ2yhEZ4kX?U#D% zizeJ|O6cY*W1O(HLE+k~72J1Q*PCT%6&+;0G*@S;+KP>>GJBN+)V80Q!kx0^pnIz1 z1(6M*QS96quUSHNE;52PJcAomFsd*KmI7P`DHUZAM^E#*J8(kD3U{wnX2oz@I>f+BjQQ(-6#)s(SQ{xP@3BELP&Bd$ zlFwq46twWP2jEl#fClXh0D+ALJn9PijbZIAG&2E2+UG=kKioid9T z(9RiNGVS9M=|-fLjY!+{E-5$u1V;wR5Zk4PZW%j>Skx=nHiNu5X~o9=<=JwN=YSpt z{+Tqn;?$%!)05;*KBWtV%Q-E*;IVWBE~wm-_WV5_LD6EtQ(1pXds11K;XHi(ZdAU* zfcvLY=HLWWbNTykMLx5SZ4sKim^C_N}`Cdnjk%x9Foe#ErU*6?A3QuziN|mhM+ssaSaq8J z5P1RZQsgOW{3yVVWo^b$j(F$DfE&z}y_^J8CEG=_9<=ppbg*(dUusY0 zV)dXyODpqjCXx@|mrasYwndtJxRSEIkW9o0*HhLd_HFJv$@p@3HQ9kZnLNH64y7y} zFT>H4b&0)^HzRAk?UtqjK9_m^vCJU5ocEk=za+qH=wTiC7j+)&fdH3TlXEL#n#3PF z50m|DZNW3-1iMiXHS2A2$!#*-a30Q*PPV!*ig)7a!s3NKnvfFYB3!Tt&_pj-#)+RE z6MrKuG;aKZv?ZAq`hY~~Z8#<9Q8w#E>Z36s8}S;0i5!M&tiaWr<)?NbKneL&Ya+Md zSGL`?koeWpuCFvCz((9bEUg0f_cFWYc28l|SVAbe&1EwT=7KxK zQjFJuG&n;jB19UjRwov1(v*inHSM*Lx|yCxv@TrJ9*wlug}mWVq}Ep-jd(-8PamW*XTzhl`4K$foH=k*YdeR$>VW7W+LZ57^mRm|V)ww~C$e(=uTA^>40#*F zBQCbHnboGq{ePuMo`}8R4*W9f^l@ve`dVM=PlGw(6^@HWi*v|`x+d@vQ7y~HG)qGe zf*Sm&Y9Ru3FcUneqlm&uHi}j|S|RWv6GE#Nd{B=O5oAJ$L+G!;2oKuz>O_kpgC3ow Liml^h)T8?wpSg8e delta 1761 zcmZuyeQZ-z6hHTNeeGU9-+SH4wr(Bkw!Ur5mC<$|E=Z%m$_6qv7!wq>Ze;_cXY@`xlD2}B|giHM1Rp+rR^1`PTKCIn+Vck9w=e9b-gcYf!0 z&%Ni~`(B5q$?!CJ{ZN|2^8DoZVGkJ{f3KBPFhcxBR}Vl7TSynNHsU9T*a#WQk8OvU zryeZ@BMb)s-lzsJpq~aHu#Xx8`dWHb-0%y!W&nxydoUyl3&JZBYf)jPuKiwQu*=8J zoY(*$?$6=yZ=neViB=@kjoh@ML3SNypF*r{VtZ|inl~dN9 znL}~pm2|J1mDt9SD2siA>99-fMo$){bPYF6RB@MhWa3|u9rGf`=0#@n&y6{rim1=> z5xr=4e_)mQxcqT=e)ER=S2j~h|8W!`%@~CN{hv6IJ#yEPY=snihAsp@oIM= zZ|>*EqU}bg^`Xhs61btFVwJ7x9u6$BMSYHKb3`-uqD%Yvfol5@_TA>w^|H?$ZR7=( z@65{MNz@n7U=p=@&993T8_xDmN6D z8MPq{(SCk+=LmL63Xx%UTk@?O!C)yw@Y?VPZy1!}tvigZ5HU8aCB;u8FQ8w9JjEVw zIJj`Jan>X&*%OG~!sbsZ!gL@PXEms!Y)~$(X;A=tSjBnlH*?&)r>|${Hr!SK500s` zAh*65HdX>Sk@KxwAAJJ*ZuW!xI2qN8lo%mnY|Is_nvx?H0S*|seM!3I$cAI!BO>g# zMJyudGklMQM_)n44)wOXb^)$3U&fPUiJr*tQb(b(&tQU<0zUi8<_dkvZKP#Xv63A4 zx_FjUlof^?xRLbUm#xGDx02pjc0KFFjNT7NdBK>3>-{j9^tfJycaz>(_I7rOV})|p zPzs-^Tt8v1WjC^4H4V!GJPNy5Z_ahI8@EM(b29rrM`b%b^(MDMIl(^lOyPlT$sHqa zvR`w%Y`@FP$OBR!UW5yzg>A~~BDL&7-onSO!zC=VhF-GYBN2L1x=*4sVfl+R%`j0K zlqr1xr-gL14e1hXqkTdK;*Fw}Ou=R5_ck~p)Fm`hLOwBC$piR?jd+)nhWgs}6Cg}Qysgkg0UV$cC0sKVE#6N1)sl;D3wgA*X7$fbd>qI_)Y#jBW c85_h%5K#;@as7`bcN#rdt4ka1k@0}(A6T_wm;e9( diff --git a/release-optima/SmartB2B.Optima.Service.exe b/release-optima/SmartB2B.Optima.Service.exe index d69d8caa28f81e6e841cfd6b49dc0d8ac1b705ac..3aa1081bb76efe0d1a16a97d48256bb2b36febec 100644 GIT binary patch delta 95 zcmZqJ!rlNvj8m@qCNU&27&4?W7%`+Um@*hM7y#*1AS)RxnhNBl0eMLbW e6gL2hrUBKPf=Lsgj0upH3{;c0{oz$cc@_Z3pAv@v diff --git a/release-optima/SmartB2B.Optima.Service.pdb b/release-optima/SmartB2B.Optima.Service.pdb index 7d4bc1aa4036513c12a4eaba7b09477cc9d5acf9..e85dfe4f238c893555409506329f4f75ccea3f80 100644 GIT binary patch delta 1326 zcmZ|OdoWyQ6aet=yV$$yQCh*WOS~VQJQVQ=D|W@C8AcO|1_=@xuZ~AaiO41xr19)k zr1cymjb~-CYYfuyXqbvfJQ^y~8i|mnXP27<__iwL2{h=7~Y%#_pJ<0;k-mog4!Uv+QJ&ojlT`R$aDLCPX+l7KdZNR(-_ z7r+gpOC2#<6fIct-=D-Fx0vF&0M!*bkK913+zz-yW6mSdVfg(@^YC*FQ zZW7Q9`oRzw1yf)K%!4Jc0p0>RdyI5}2{;0d0SE9g_{5(6@)&tTd>#aY2oMXd@7FRR zrseL_DTIJly002mTKyg>hR~pH5KK0_wq@@X^hXe=%bq~PU|dvA1j+IiWD)X2Oe6je|Z6NxMwJak%X}9>(XHC)=h5j)mBHdC@aHa34k$&jU3c<^Rz9$ZIZ0e}Y_vCrH4mAFG@%xra6%N5GNUOiET$3>p-l9HM?xNKf`J#I98CiEl z)lJ~1mD*}Dly%*5+dJS~S$SOcsSs9C@vr4Jv!=S#j+Lym_4&Mz*;*ux?knXVU=5vH#cqlF$}&VkLTTAqea8rSvC4C#huY)q0)CP7Wv1MizVT7PlCo5(kENP1~AY z$K2iR6EQzdw{f_08?Tv@OHRs5J%KxGs%?DB2GRK@8S6ssTuT%&DH~Ah_4KaIUkR%m zDo43ME-k%0eL`fS60M+d;ZZeuh)_owr)r_R-o1>?YdVrE^EcJV(P8`En-J$Bbq*h}c|gr2Z`y zmtb)f7I$IsBP<@p;#n+SqmJ_HO#i!tB}Q1n!;(u_l7uDsSR$ebfmr{4n%l48_Uw1f zqA9@}Y<572MCt?#5+)MqDNxfmeq(_N0UUWamkea~9!m~!2t+NPd~RO_TW4W-B7r9# ZCdi*2He=Z315Y+Q_wPl|DShp){{S!fy*U5? delta 1338 zcmZ|Oc{E&S6aet=8_OGe($v^B1VIp0YF|PmjV*MNrm0M9A=TRINRFkJ2pUUb%###3 zC_yA5QG++5m2xCnOHE^|Ny=#sr&LaD35tZ?htt2>ch2v9_kQ=jH}lSW_evhl$iv*2 zy{{b*+UFV(9gGmlZ>(y_uypXue$cP(6sE}z4rYhXFW$PC7PcTrsJp(-fqx^D4kfh_3BtmS&L{iWu z2My^vxisWakZVh9*X1D3gIEvt=ze*~ACiv5Ni9Vi`V~M4c0@K(uu21BE5A=ZAk+wF z+5ND0hZGT7dn^e=(6vBWChBkql$Alx`I|%=-rFYXEWEY8%%Lo5uAOUP%>-P%F;E<( z_{d+lDk&5Ps_=i4S&&FIFcEgYYEe*qYF-i0x#26PypVpPUTRj{sUJS{cM@mfQh7T( zKs_n??3v51t~u!+I=O7m>`7Iz&okdE3YWA!(nDw5ri1i;?(tm7A1%G=H(oV2Nc4Ir zbQvgQchn8`_icnN52l1CrVLnVRvDcM3QRgn>U`xjOgW9#4mj_a98?{Vfcwl z;O8d?uFv+UXjodU7U5YR**i?j7T@4`$$`QVTVplZr@vorQvBsa!*!3xOv4vyRijVh z-8K`C@@{cnKGZ)`y;;0EG$2oOc(UEb6Aj)h#oRPGRvWJt?%gL(tV}!p>DnA{mZkTr zNSHaSP_kSi?$$L=PPOT^vMbA<>W=LEFoZ`YarH}+UoS;f?QT@`%TyhcICyOL+CCTS zh3GeWQ%diubl0wr=dVU(Txczq9zO8>@xjKTzJ{K=a_Zh)6TJ)5FD*MOOY+PfN9cx~ zzL6bke647sUu<0XrAO!~o^t71@lCBAkB$^Nl;=htJY7+jJ@Okcx$ z-shjw-{zKCc04P~Ev|;o(!~0#uQ64IscKBMW2y&JBbfRFQ!AwDp*q9=E@8obEO5qx zP%KEs0ul?Fd9IZ1|MUt|urPnSmoIi*#Cm%a2*hH*XkkVIJr~L>yR<1L1TX~frAi|W pMH%wdVX<8qWL_{y=K>KwcVL;b7#UcanItBqm>O85nVY7Wo0yoSC7Y#9Hu7;|*>_^+{>c?S0Rqw6S()Zb z8hS4+x!%=#v?+D+4WDKOsNiXsAW*e^h!y*RG@~_DXUa6PHdp(8WcD>Rz~_4UJsw zpb8A-e;93}m*g?27}ljW?x%z}4_eCf{Ud6>@An$galg0cKJIqTob&Zz8AM(~toorN zzG zuL|QWTGve@k%e9^$v+u+lXA(!%WTh#N4+(PUuNGNlP8(l2R$tHFU{`-RcQ{H3}wNy z;T_!?4r6re_|W4Em6DEdPRI|LD#G}+NBwRn$|;a*m0QAjkvWy@gUrJ_OKuxncqVUI zOYuy3%zWi~(SkU)=7H2yao0#Qb9$qhw6iyOw#vQ!+>y4qxT@~tg4bf&Ky#pDlp@@`X2rc9!W;Z}nID-GE904>HpuB3zcp+-CiFOv#HGEV3`{x)wYzFj}nm zJh5HL!{bPy_s456EaV+O^Z_$HZD)R z>if_4!#`sP0Zr5hlGA1jw0=gwV0;ea0?Rf51xZ{u)KC`R+1v veA{jFl?uD_s_0I`*&;j5@XAZT@L?j|Dx^z9y6s4}8|e-qU72C2;QgGx_7OHJ diff --git a/release-optima/SmartB2B.Sync.Service.dll b/release-optima/SmartB2B.Sync.Service.dll index 99652e80c08af09d7fe9c794c157f2b6428f6da1..e40ba0fa8292f1d63b430403fcde184fa5b28a6f 100644 GIT binary patch literal 57856 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 JhTi>7`F|5}tbG6g diff --git a/release-optima/SmartB2B.Sync.Service.pdb b/release-optima/SmartB2B.Sync.Service.pdb index 31edbbdf28975e997315963cda816b0cf65d4583..6a56e967626cfc5b79ed935a0db63dcc6fc326ce 100644 GIT binary patch delta 5129 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 - + diff --git a/src/SmartB2B.Enova.Service/Program.cs b/src/SmartB2B.Enova.Service/Program.cs index 231300d..0a236e3 100644 --- a/src/SmartB2B.Enova.Service/Program.cs +++ b/src/SmartB2B.Enova.Service/Program.cs @@ -11,6 +11,7 @@ internal static class Program { public static async Task Main(string[] args) { + ConsoleLogger.InstallTimestampedOutput(); IDisposable? sentry = null; IErpOrderAdapter? adapter = null; var cancellation = new CancellationTokenSource(); diff --git a/src/SmartB2B.Optima.Service/Program.cs b/src/SmartB2B.Optima.Service/Program.cs index f04b670..92da474 100644 --- a/src/SmartB2B.Optima.Service/Program.cs +++ b/src/SmartB2B.Optima.Service/Program.cs @@ -11,6 +11,7 @@ internal static class Program { public static async Task Main(string[] args) { + ConsoleLogger.InstallTimestampedOutput(); IDisposable? sentry = null; IErpOrderAdapter? adapter = null; var cancellation = new CancellationTokenSource(); diff --git a/src/SmartB2B.Sync.Service/Diagnostics/ConsoleLogger.cs b/src/SmartB2B.Sync.Service/Diagnostics/ConsoleLogger.cs index ef5a16f..dd6ad4f 100644 --- a/src/SmartB2B.Sync.Service/Diagnostics/ConsoleLogger.cs +++ b/src/SmartB2B.Sync.Service/Diagnostics/ConsoleLogger.cs @@ -4,6 +4,12 @@ public static class ConsoleLogger { public static bool VerboseEnabled { get; private set; } + public static void InstallTimestampedOutput() + { + Console.SetOut(new TimestampedTextWriter(Console.Out)); + Console.SetError(new TimestampedTextWriter(Console.Error)); + } + public static void Configure(bool verboseEnabled) => VerboseEnabled = verboseEnabled; public static void Verbose(string message) diff --git a/src/SmartB2B.Sync.Service/Diagnostics/DiagnosticsHandler.cs b/src/SmartB2B.Sync.Service/Diagnostics/DiagnosticsHandler.cs index 6395920..053735a 100644 --- a/src/SmartB2B.Sync.Service/Diagnostics/DiagnosticsHandler.cs +++ b/src/SmartB2B.Sync.Service/Diagnostics/DiagnosticsHandler.cs @@ -88,9 +88,16 @@ public sealed partial class DiagnosticsHandler var compactDate = date.Replace("-", string.Empty, StringComparison.Ordinal); var path = Path.Combine(_logDirectory, $"{_logPrefix}_{compactDate}.{stream}.log"); - return File.Exists(path) - ? await File.ReadAllTextAsync(path, cancellationToken).ConfigureAwait(false) - : null; + if (!File.Exists(path)) + { + return null; + } + + await using var log = new FileStream( + path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite | FileShare.Delete, + bufferSize: 4096, useAsync: true); + using var reader = new StreamReader(log); + return await reader.ReadToEndAsync(cancellationToken).ConfigureAwait(false); } [GeneratedRegex("^\\d{4}-\\d{2}-\\d{2}$", RegexOptions.CultureInvariant)] diff --git a/src/SmartB2B.Sync.Service/Diagnostics/TimestampedTextWriter.cs b/src/SmartB2B.Sync.Service/Diagnostics/TimestampedTextWriter.cs new file mode 100644 index 0000000..7b84407 --- /dev/null +++ b/src/SmartB2B.Sync.Service/Diagnostics/TimestampedTextWriter.cs @@ -0,0 +1,93 @@ +using System.Globalization; +using System.Text; + +namespace SmartB2B.Sync.Service.Diagnostics; + +internal sealed class TimestampedTextWriter : TextWriter +{ + private readonly TextWriter _inner; + private readonly object _sync = new(); + private bool _atLineStart = true; + + public TimestampedTextWriter(TextWriter inner) => _inner = inner; + + public override Encoding Encoding => _inner.Encoding; + + public override void Write(char value) + { + lock (_sync) + { + WriteCore(value.ToString().AsSpan()); + } + } + + public override void Write(string? value) + { + if (value is null) return; + lock (_sync) + { + WriteCore(value.AsSpan()); + } + } + + public override void Write(char[] buffer, int index, int count) + { + ArgumentNullException.ThrowIfNull(buffer); + lock (_sync) + { + WriteCore(buffer.AsSpan(index, count)); + } + } + + public override void Write(ReadOnlySpan buffer) + { + lock (_sync) + { + WriteCore(buffer); + } + } + + public override void WriteLine(string? value) + { + lock (_sync) + { + if (value is not null) WriteCore(value.AsSpan()); + WriteCore(NewLine.AsSpan()); + } + } + + public override void WriteLine() + { + lock (_sync) + { + WriteCore(NewLine.AsSpan()); + } + } + + public override void Flush() + { + lock (_sync) + { + _inner.Flush(); + } + } + + private void WriteCore(ReadOnlySpan text) + { + while (!text.IsEmpty) + { + if (_atLineStart) + { + _inner.Write(DateTimeOffset.UtcNow.ToString("O", CultureInfo.InvariantCulture)); + _inner.Write(' '); + _atLineStart = false; + } + + var newline = text.IndexOf('\n'); + var length = newline >= 0 ? newline + 1 : text.Length; + _inner.Write(text[..length]); + _atLineStart = newline >= 0; + text = text[length..]; + } + } +} diff --git a/tests/SmartB2B.Optima.Tests/Program.cs b/tests/SmartB2B.Optima.Tests/Program.cs index f7024a5..6734e5e 100644 --- a/tests/SmartB2B.Optima.Tests/Program.cs +++ b/tests/SmartB2B.Optima.Tests/Program.cs @@ -1,7 +1,9 @@ using System.Collections.Concurrent; +using System.Globalization; using Newtonsoft.Json.Linq; using SmartB2B.Optima.Adapter; using SmartB2B.Sync.Contracts; +using SmartB2B.Sync.Service.Diagnostics; using SmartB2B.Sync.Service.Orders; using SmartB2B.Sync.Service.Rpc; using WampSharp.V2.Core.Contracts; @@ -26,7 +28,9 @@ var tests = new (string Name, Func Run)[] ("Wynik Optimy zachowuje kwargs WAMP", HandlerReturnsKeywordResult), ("Operacje zamówień są serializowane", ConcurrentOrdersAreSerialized), ("Fasada COM działa na jednym wątku STA", FacadeRunsOnSingleStaThread), - ("Adapter serializuje bezpośrednie wywołania COM", AdapterSerializesComCalls) + ("Adapter serializuje bezpośrednie wywołania COM", AdapterSerializesComCalls), + ("Diagnostyka czyta log podczas zapisu", DiagnosticsReadsOpenLogs), + ("Każdy wiersz logu ma czas ISO", ConsoleOutputHasIsoTimestamps) }; var failures = 0; @@ -111,6 +115,84 @@ static async Task HandlerMapsOptimaContract() AssertEqual(123m, request.Items[0].UnitPriceGross, "brutto"); } +static async Task DiagnosticsReadsOpenLogs() +{ + var directory = Path.Combine(Path.GetTempPath(), $"smartb2b-log-test-{Guid.NewGuid():N}"); + Directory.CreateDirectory(directory); + try + { + var diagnostics = new DiagnosticsHandler("test", "1", ".NET", "test", null, directory, "service"); + var invocation = new RpcInvocation([], new Dictionary { ["date"] = "2026-09-18" }); + + foreach (var stream in new[] { "out", "err" }) + { + var path = Path.Combine(directory, $"service_20260918.{stream}.log"); + await using var writer = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.ReadWrite); + var content = $"Log {stream} zażółć"; + var bytes = System.Text.Encoding.UTF8.GetBytes(content); + await writer.WriteAsync(bytes); + await writer.FlushAsync(); + + var result = stream == "out" + ? await diagnostics.GetLogAsync(invocation, CancellationToken.None) + : await diagnostics.GetErrorLogAsync(invocation, CancellationToken.None); + AssertEqual(content, result, $"odczyt otwartego pliku {stream}"); + } + } + finally + { + Directory.Delete(directory, recursive: true); + } +} + +static Task ConsoleOutputHasIsoTimestamps() +{ + var originalOut = Console.Out; + var originalError = Console.Error; + using var output = new StringWriter(); + using var error = new StringWriter(); + try + { + Console.SetOut(output); + Console.SetError(error); + ConsoleLogger.InstallTimestampedOutput(); + + Console.Write("pierw"); + Console.WriteLine("szy\ndrugi"); + ConsoleLogger.Error("błąd\nszczegóły"); + + AssertTimestampedLines(output.ToString(), ["pierwszy", "drugi"]); + AssertTimestampedLines(error.ToString(), ["błąd", "szczegóły"]); + } + finally + { + Console.SetOut(originalOut); + Console.SetError(originalError); + } + + return Task.CompletedTask; +} + +static void AssertTimestampedLines(string output, string[] expectedMessages) +{ + var lines = output.Split('\n', StringSplitOptions.RemoveEmptyEntries); + AssertEqual(expectedMessages.Length, lines.Length, "liczba wierszy logu"); + for (var index = 0; index < lines.Length; index++) + { + var line = lines[index].TrimEnd('\r'); + var separator = line.IndexOf(' '); + if (separator < 0 || + !DateTimeOffset.TryParseExact(line[..separator], "O", CultureInfo.InvariantCulture, + DateTimeStyles.None, out var timestamp) || + timestamp.Offset != TimeSpan.Zero) + { + throw new InvalidOperationException($"Brak czasu ISO UTC w wierszu: {line}"); + } + + AssertEqual(expectedMessages[index], line[(separator + 1)..], "treść wiersza logu"); + } +} + static async Task HandlerMapsOptionalExtraFields() { using var adapter = new CapturingAdapter();