From 015e26dd406b741e558eb6bb44e775e214286b02 Mon Sep 17 00:00:00 2001 From: Tom Kirkpatrick Date: Tue, 13 Feb 2024 15:30:17 +0000 Subject: [PATCH] Implement pino logging --- README.md | 1 + bun.lockb | Bin 5553 -> 18012 bytes config/custom-environment-variables.json | 1 + config/default.json | 1 + package.json | 8 ++-- src/server.tsx | 47 ++++++++++++++--------- 6 files changed, 36 insertions(+), 22 deletions(-) diff --git a/README.md b/README.md index ae30344..f4ad5de 100644 --- a/README.md +++ b/README.md @@ -72,6 +72,7 @@ Here are the available configuration options: | --- | --- | --- | --- | | `server.port` | The port on which the server runs | `3000` | `PORT` | | `server.baseUrl` | The base url port on which the server is accessible | `http://localhost:3000` | `BASE_URL` | +| `settings.logLevel` | The log level to use for the application | `debug` | `LOGLEVEL` | | `settings.timeout` | Timeout to use when fetching data (ms) | `5000` | `TIMEOUT` | | `settings.feeMultiplier` | The multiplier to apply to the fee estimates | `1` | `FEE_MULTIPLIER` | | `settings.feeMinimum` | The minimum fee (sat/vB) to use for fee estimates if we could not determine from a configured data source | `2` | `FEE_MINIMUM` | diff --git a/bun.lockb b/bun.lockb index f28fb66dcc3e22d5c67743f5562e2420c3e53665..23090eb4dba675e6d73199acd51d46a505277dd1 100755 GIT binary patch literal 18012 zcmeHP30O_r+dtKbgd{Rc5-QGVE=9?hGK4~jG@a^H=bW5#8eNqPp{`02%8;>K;Zmj) z8IwfFa80*xqYw?QLcaIi=d5flmHU0q_y3;fvwHS<_u6a!e(PQDT6;}U$ zx^wxu9Db0xdmvvC4wk>b!_SNB&tZ89ggiGfD@adKmcd|T+H4Gexx7bI-oE}_8hW0& zYraO|uOXl0D|-#koR!*CcfDu=+yp^SA{Yu^$w+DZwXXDp68#yB$N(;1fDv;U2BR~? zyMXKjQV*me$Ye;vcwdOCf^2|z50I50yMVj}vOCCAAbWxo1^9Et1`Nh+IZ1i|lfh7e z>t{fA1Q{R{cyL4_1}BKa7mFAS_dqW%j*!9NayT4QV7B9fJA*O zK%zbmrEw$RLjIv3kq2x|rDFu|=au9X6=sC>+Nf&K)85*8y`@fhw-@P+YTd%T&TAVC zUCf#@r?YdC`Ki03W+nOES#+iGMHBz+Z~2#&Z7mzpwmeYi?X5z-qUp%>N2n*du$(Nm3t=( z9<|>+c7p8dt>{n}Xbs?L&QUod z_hP4NpZ7ZxFtSrYv6c5mZD-baqQ^M>u6cqm^!YE!mb!NIW` zH-xw;o=d%3JoJ~K_d{iNP7KSotl9Wr-H{n9{?e=M7_>~id&AnS=jEH4)P_`Xr)Xs! zcorrocwHTCb@5VgPdoPEaqk}JcleaB)m2<3v)d`6Q$M@$4VPnbFTMHIQ?sz0cJ5@o zC3TBlcwbqmQl$aS`M(wLsl?y~hd$INR69cjFSIcbyfr8?7VsE{CeLWAUIf1i09Jqp zD1%(X^VR~n_Y&Yo0UjRL=3b*UET$8@Je*hozO8x_Zi1fxCo=($aV$UT(Uw5)$#CKT zc*J5LQWE?AFTq#A$wa`nHDAI=@cICRJ|+^nDat0~I=SzAlH9ih@UsDr_WKbV68v9) zhrT8f%T2C*FHib)a&I31V)+pdU2mH?2tFKu;{lJl|A-9<{tDnN0Z;O7s|^UgBLGJL z9Y8UK13b zBrQMc-_}6%UkrF#z+>JRepLU9QamX;;gzs`|Cij?wY{YM{M-7o13dPB#CC-D`#DQe z$bB(@hv^R0e_`3l^|s=3rFhgI+b_&j+7w7W)qtnBUzl68DG)ph1}>sMUi;DZy8!T3 zP=3r5^ZwEL-wOEAfXC++^Zrr1K4dx#@C5s#_z1vb`^B<@Dcc-~{VoAsPnv(5!EhtN zw}XNs9`%N3`akIow3@p9XkrKN!a{5IeTUL-479$NrZ*H$RHM1$gX#(C#>f5T3T? zuL2#$NU8pa>E0Spnojhe3ixr-{P9{_?MU$P()>|xanSWhvHOqA!Lh%>1FC?s8*;!JmkKB`-a`^?lSG|*N$*FAw#0QG@~FXq;ad`M>X-;Y zo%)qX#0`|jza=qULz+&PczuxcI$bKkHCU@qfi5wBLpTrzeF+s%VjS1d82*h!JUp9J zK#6fvNtF8iX@5z5{AcXn)TIe4Ex*by}4CXw~ksmoMphotN1$cj2y_ zdnOuFQfI2M=kg}6iP`uf9Eb=n=0O6p;%L=AkI^GEFQ*@ljJ8R0=rW6$|KNS;NKS5I zzx>Vew!IyyCif)gg+7c48ltvPnnlaHkvJ6 zw`Q4ghc4xRW{*nP`K-%n+3clFik7~?u1b$~zvkUOc-}o&_V}v1g^jWwIJ&+@mKkRP z-mHrn+mYAM2gg>zOYf(d@i%rTZ5#M1RXpEg()(q7i&rKziJ$b7|MmET{dq#)V-^t? z*XML?H)XH|Lu9_Xq(kGY6{Dvb8MCq#eNDJ~gcjK}UL1o+U@r1HE5})7H%0&Vr}N95 z2_dZzgg8hj*YQs;(V%V$)XoqZWsp0+`6zQwI^ zw}6P~OP^aYvm>*|Il5lz8yz)Q_2cpv_d1835S2z3Zp~?on)=S(Eo0N!qctm@ulDm_ zvFm1fZO)xXz6Cw0(A4NJ2wSQ=QU zWidV^LgSa>3C0?p3unkyHu+qh5kL0IX+H~}`-+o)bN$faopGdH-;OV@(0H+LB7qqY za@8{5GOyRCBOzlif6y@KU-ZbLtjQv@NZhkQcVdE`YkErJvD7<5S9UL8#4Iye^~%PA zcfftTS;_!E8~drnD}jjE0j4|6fw}&YOW%mMel?SvCNHR0a-Ci>tld6^9A^h@qrU^E z{1FjfGr5bO-@Jb5>6c=&>t~smmvN0l#%=h0##$fmGsB8q;%U4%hLOOWQE*@L>CP>O zJ$vrByx>Y@fXG}cL{;mqYL(Y0zmyG~oj+bGiJ!x0ueUc^yy0P~!>!$p7fQUe6-M}V zxTfS9-fb=r5q)8JZVt>slLN{_eM2{2V2NBOgs53ri|XH>RT^ho5PGkFSDty^C)UM3 zund=YwJh zjTgr_5}5lpU*9pUaN*tE+P@!IvSZ;G4ZoMaC)qfeO)k;7xgcX#mQS_ahR|(q5|zdU zpS3eBTl)N1g*z|l*!w6KU%q=o)O;W!c7VO^=D=K7vL)hgKgYQSVhfvtMXyvp8Q-wE zn_QOoen_gw>)gVM(1@EJiLp&{OB|;3&9&^d{q5+-;jVT$HnCmT=ncFk|C+|D+{_B| z|Ban2?=~p=%hry|7VH12ka736QAJ`_)3EFIi?1GJ_%V{B_H252usnvxa6croZ%)L3 z{+;er7(QnO-W;+#!Mbk=jkhbES9L_x&ilMGL!A0ebY7TMuyDh<2{UE4-rw64e?Gx% zam8!>A`5Syo-ETNN>zpBhVME~G8y^%A4LM)foZSh+^hD&{Jz-^^!XJtuxRhHk+*NM z&69%W&EA$Vtc<7MT~)labJgode~mOLj#+moEoabg@)w3p>iDYAH8WScw0L+h|8IkL z2c4eH>QL!Jti#bAbyF(JS4Y)_uWY{>2JN~+=YuFHo_(+AR_Gy#|{#hCFM3A>2rpA*B>u={mbo_?b4c-=AN^U z485`HZpdEItqWbX_neOEr>~r{r@cqcJ`+#fr5D1_s%|#EduLKP??mcBAR@f*Zl*af zpIgom{Kr3?d)3X)vs!BDcsE4n~;KJ-v9fQ!u+XQ z9}X;3>9u>LJGz;WIxmTdjPTkFKVfw-1bG=G3 zw00J5QG6l3x0%}|tc%loPtz?Q`bLwU;3Q=nuuoaEyng#8i-TKN(0KdN zd0jl#FFJat|C0K$GY=dZ4VIRz84z}7LG|iA<~8e5Rh%EO?%%bvKVO`jKU?dW-ceKM znpqbj_T4#cY#1Wy5z%8`A&nQ;B_uEx`#jtgeRR;SlY6@KSZO@0pPVA+mxR4{PxSx0 zyN_v%jBM4-y^0IxRa(c2#0fS_#>v=r^D6Y*=5v+EYtDqG|$GlJ9j)06f3{iEEk{7SmHm)P9zR@%2(1B%6H}* z_u!h9bB~yEn`pcPkWd;9!IeExDy+WH5T$rnK6^^ z?Okn8;~hxn)omwi+omp8ZTMrAw6^5tyPh6N5&;}wd&n3U~KeMxj1gH z!-XIx6^Cw|UpuK8l64}* zo4hRJgOPvO>W`=MmgUaRoAzXARq&MfcXyi#7rRUvIAvmKU54G{c@DpCepOwgJTg{4 zJAX{sF>R~5dDddt+!t3D(s(tIP#TzxFN{|U+dI^0ah;>D^h*xrxd&WL-SSYj$kNaG z@z~o6#WOUE4?lVM!v4Sug{iOVaxXS26slZ(QWrR&(#=Zd)l=Xh^){H0f@Izs9%)^; zB>usj6Fpb?25LL99UdHM*nYa^^tE5C^-9-`lIwq>A0y@A-t_vMt7{!BA18ReD}3Kx zF==mxZ{+!0L!3hr-XV0}N3k*=*AzJ)sg2#~F@5JBkGGq6A5E(A^jz^aPsdivB5yDC<955Je;N>#n|%E~BVd5#jYj#n5yxlV9+##o8a-Lq`EL*Z`hl~b z+U=X~v8BuW<<=^nvgU3&sj=oTeLks8=hX>&Z&YP_KQO`7&wAUY#|gW(?B4m|h>B{j zPOR&j`^>x|+G}MvKPe6sI?mpERSGhG~6s-w#Ig{H3#o%ha1?du5> zi^Rv3FO>y%*Lb;oYU7}RVHM(;U5^FLFz$44@X1ph)C_EkXKHQ7 zjj4k5H^)p_s7K=+M&}*)M((0w4-GT5dATn0PnYjd>h7Oj#`@#LhskSa4Vb9+u+U*~ z)m!GM2e1BKQB-gI!2Y4ugNnZO`R5Z{tCv<~`c0$+D#J zvgo|b0dmZan``scSIX|XdOqIvenEAvtspHpF4{d!C8XEr%+WETg{iU0qs_UCHrmBl zL=WB9{fW!6bIj+JnR1DFvuV6ICXv9LQZw3T)q#(7=_P}A9Tf!pHhK2Mol0|0AM5_~ zPUzSy6LzMI?(+2YL3^@fd#@R|At-uGnTd|ds^=X(CWh*&)}MUlP{4O%4E zZF$Yold35Jw|mvy*lsnf>!1@ej|NWiUwdno=|jQ1-u@9wC;i%K!RpJif>MIYKVG~O zH|BI$_zb&k^EET*Yi*({N?hBM?@{2x7`Cs7p8E6r|FZ?KZIEwz20@1nbH&JS*#qyJ z00*pxBY(D`Z&~O+bB(?q_@B|>XRbdj@Y4c6E%4Ie^Y>?y&;HpCLJr4L-9S%W#0}#JyoReAsk`}ez4-z!nDCO&^hpvhj_a}z zDW?%`%tBBc6=-N+3DED5;9Lyn$+!-~_mlW85#RgaJ38D8F@Xd3gK+N#_gQdH1otm+ zuL1W3a1D>^ZCo4UIu_TQs0XT{0SE4V;rlaG8Q=5ZI~ja`q6`PVm%zP#+>b_e;oCFn zn+e?S#l2bFN5wr)Lpapo!2Lwr`@{W8YU3H?CV`TZ2jY<%^T0i8v;meI z^}s!M)D?Bc@}nKlHfR&H53v>AkMF}^Z9#o6f@Q%nVcAGIv26H`1m6!}nXoKqE3_Hf z4sD3GM4O^*N#1BP;y)oPGlH!@0t=K3si*<*oRF1qkrs6aq@dQshXGO`BUElb zq+m&jmjk32Knk#(f)r>Yk;K13Rwf7#m~snJ;O$Z*@xTC#iNvIpkOFNYlK5y)`B27g zfE1|lNaDo-DMo++V-vp{;{O3DdSGnGhj`u)4-iN(kl32|=n!8KDj!qC5N{shRYGAX z4Zfex_w7b}d5BL5u%XtF5ApUPUMHVZT%i#wLrIAr38fo_As#=(^8`}RZeRoA6GVJd zD2yTIL%fEF_X?!wQB6dT_!kjB7f8_u>i~v$91+hKS($KSiA9Nz5%G1AVxS!mFC^j( zL#04VU@(Xu67h$D6k~}EhzAn!gprjoV240Gf8MVkzA%6>01cp|#7l^Ht57L=Y*Pk< z_z@9*7DzE-n;?dG8WE2dNP%)sCG@fm5A32q)4?U{!GNLhGL^I#N&y0 z-araGa%__ydrHVNNBpaZpAVG}rS<_+Z@e~{J>mvR| zpUXo$xrj#*RUYaICO%)p_lQcNdNJY!M!b<^WuOUA;hPvrw}19kI#LYr`69kYzy=kk z554zvX%9~1m$L#9hZn>VvL}RyIYPdhzr9$<<$GJI>woU#M>Kcxky55}*fm3du@S}t z{qGG240o>BL%`*;-2FLxPmU+ci^E}YL}D&D9SVe2;?Mw&NEaLurDu}9TN>dDJUJ{6 zHxC~UcEYRxAxA6@mGXJAgaIC(Z}1U|;o}osT_MLCeCULsY<>XGSHu$_*%c2BJ z(si@N-eHhCkL$q_`Exh{UTz{WOUUtb^AHR8EKUel%<|{B`LVoUjzs0`<_?^Y%7S0M zC_o?-Q778vMC z0RcVAq6UXn@Sk-C^ydi6kPQQ6D_D9(0Gb|UVe4%T|4k#J8s9Q5WevktH2QYM0p+(7 zSU5x(wZi#T+W@k!u7IstFYC8j9a7=b@l|7FnLt-+(3(~V{Ac4Pl>bbD8o@e&)`U%y zG~AY(r)1~`PRR+F3uYUwDE1XQfWNu|EI7vEgX|8EBMbTsu~6Xe504@BAT99ZctGzV zY@yMAc_Zrg1rmyiRRTFsElDz&Xo(Kno8&I!`W$1SqOCoF($)Y-(k`Uaj#dmMnaKc5 zassVLs&osQHY+JPftG?(YAC3?n}}m##PSuj0G3W%AV=vL*s1m6H8TUQ`5cfq$%c$u z$nWdw1%j_HeSUN(Be2A7LT`?kCGz36)NB6ZUSdQ#9_kM2p%oSXF=hbMKdwQ~gNACk zu(W{)IB2mp)$8Zc5Wt@!P=?lXrskFaqhyV7kW=c(p!#!HF(_Q9zG? zgK5jvDw#3^LUIBaoT9Xh`9c?fei5f~ZEXN2ixmKqQ@|O(1gGVkCCeW`Nlw~SG1A2p zfTU+sH`JP4zR}!(;Tu<}$Gf%0-`t7`2exRca$7@wei8usIRYa#tS(!zR`cTo(B^Z{ z7ize*;{RjK02H)NklIjcCHF7ZAe099FFv5q_}6kZOQEok0UZ8+mFB4{MyORz3(s}) WJyI}rKScpMO^~rFysarAAFaxG)IDD)JbhNdpTi zIHg1xuQUkJ7A6`)0mqaioWW)?hM>X$B}CI1lF_uKuLo$Ald%>B-Hp1*VNJ@-u3 z(w2z#u>qp`D=0Va`lnUF=KDWvGT>m_)6)Mfu6H|9uz~O`g9*RqsS^) zzndtk$^hHw5NmhNga~a!BRx!Mt%8#RV~c3-<&{Y7p{cIoBu<2ogAd zQm_MAG!1Vd%cEfgSrf(qcnD7kZ8EtDqIbr{(m(KwjQ)QIgc4UX{NSYnt(y>JQXTC8CDL@5Lum>n zE`)ifL!-M8>b!OIdg$~^hg1(C2>o@>v701?ITmI3^uE7A);W9ds_CVN?Y>E$wEte` z9C_+(56^|88%KX0YH`11sXcz>%!_-+P1H*2&CJQ-sSk4n7cAp$CzEf!1NS^6m1*C! zKlW{UzS^lk*C45qox8mJQ_RJ#yPxGQxqP&#zhY>D;} zd!LRv)U+#ad6%#O3!$kM=M_9ka>6V*4rI9+h9{0Ugx~PVy+1QIk+$&Lbj|5s3j1E0 zQm^Wa4FNpomGh4bp6$_Tt?8%yYAnNhT6nH+yjdAPQ06H4)v^dDH%cn2PA`_4Z*PC< z$7h20qO*fvEQNPJI5%Mml(ywBUo$nIXyf-l=1fcWv-_Sjdxnnq%#L+FdN`)1%7$j$ zTBrIhVL5DdW{FbH%bsn$ImwpPWfE-W;IdK#;Bm{XuV!(yo2f-B_L8I-3 zpAmtJ)*VF3P_LC$D-m>3#kkGI$r%z<{%~07?N6GN^ciVDa*X)WDdMHIb*GteO(ECM zx~;>1M_l-Dm_8=GOoQbwrCbR$>KK?*?~oX*QB|R@ zh9e?a}!ypaf$fKykVx|)0c;JbG4x8xd0lT$%Fs4=Y z&TrMzFt;6O4U{J*d0~_}r!>)AQkY$&*k6#9ZTl@Q0!ysaeN9rx6vag{rZli5`9|19 mpos*^tUFRM2@meiGG&@%Oj?r2-(G=14.0.0" diff --git a/src/server.tsx b/src/server.tsx index 578f235..ad35d07 100644 --- a/src/server.tsx +++ b/src/server.tsx @@ -1,12 +1,13 @@ import { Hono } from 'hono' import { raw } from 'hono/html' -import { logger } from 'hono/logger' +import { logger as honoLogger } from 'hono/logger' import { etag } from 'hono/etag' import { cors } from 'hono/cors' import { serveStatic } from 'hono/bun' import config from 'config' import NodeCache from 'node-cache'; import RpcClient from 'bitcoind-rpc' +import pino, { type Logger } from 'pino' // Get application configuration values from the config package. const PORT = config.get('server.port'); @@ -24,15 +25,23 @@ const BITCOIND_USERNAME = config.get('bitcoind.username'); const BITCOIND_PASSWORD = config.get('bitcoind.password'); const BITCOIND_CONF_TARGETS = config.get('bitcoind.confTargets'); +const LOGLEVEL = config.get('settings.loglevel'); const TIMEOUT = config.get('settings.timeout'); const FEE_MULTIPLIER = config.get('settings.feeMultiplier'); const FEE_MINIMUM = config.get('settings.feeMinimum'); const CACHE_STDTTL = config.get('cache.stdTTL'); const CACHE_CHECKPERIOD = config.get('cache.checkperiod'); +let logger : Logger; +if (process.env['NODE_ENV'] !== 'production') { + const pretty = require('pino-pretty'); + logger = pino({ level: LOGLEVEL }, pretty()); +} else { + logger = pino({ level: LOGLEVEL }); +} // Log the configuration values. -console.info(JSON.stringify({ +logger.info({ mempoolSettings: { baseUrl: MEMPOOL_BASE_URL, fallbackBaseUrl: MEMPOOL_FALLBACK_BASE_URL, @@ -56,7 +65,7 @@ console.info(JSON.stringify({ cacheStdTTL: CACHE_STDTTL, cacheCheckPeriod: CACHE_CHECKPERIOD } -})); +}); // Constants const MEMPOOL_TIP_HASH_URL = MEMPOOL_BASE_URL && `${MEMPOOL_BASE_URL}/api/blocks/tip/hash`; @@ -84,7 +93,7 @@ function getValueFromFulfilledPromise(result: PromiseSettledResult) { // NOTE: fetch signal abortcontroller does not work on Bun. // See https://github.com/oven-sh/bun/issues/2489 async function fetchWithTimeout(url: string, timeout: number = TIMEOUT): Promise { - console.debug({ message: `Starting fetch request to ${url}` }); + logger.debug({ message: `Starting fetch request to ${url}` }); const fetchPromise = fetch(url); const timeoutPromise = new Promise((_, reject) => setTimeout(() => reject(new Error(`Request timed out after ${timeout} ms`)), timeout) @@ -101,7 +110,7 @@ async function fetchAndProcess(url: string, expectedResponseType: ExpectedRespon if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); } - console.debug({message: `Successfully fetched data from ${url}` }); + logger.debug({message: `Successfully fetched data from ${url}` }); const contentType = response.headers.get("content-type"); if (expectedResponseType === 'json' && contentType?.includes("application/json")) { @@ -134,7 +143,7 @@ async function fetchAndHandle(url: string, expectedResponseType: ExpectedRespons return result; } catch (error) { if (fallbackUrl) { - console.debug({ message: 'Trying fallback URL: ${fallbackUrl}' }); + logger.debug({ message: 'Trying fallback URL: ${fallbackUrl}' }); return fetchAndProcess(fallbackUrl, expectedResponseType); } else { throw new Error(`Fetch request to ${url} failed and no fallback URL was provided.`); @@ -155,7 +164,7 @@ async function fetchMempoolFees() : Promise { } const data = await Promise.allSettled(tasks); - console.debug({ message: 'Fetched data from mempool: {data}', data }); + logger.debug({ message: 'Fetched data from mempool: {data}', data }); let res0 = getValueFromFulfilledPromise(data[0]); let res1 = getValueFromFulfilledPromise(data[1]); @@ -184,7 +193,7 @@ async function fetchEsploraFees() : Promise { } const data = await Promise.allSettled(tasks); - console.debug({ message: 'Fetched data from esplora: {data}', data }); + logger.debug({ message: 'Fetched data from esplora: {data}', data }); let res0 = getValueFromFulfilledPromise(data[0]); let res1 = getValueFromFulfilledPromise(data[1]); @@ -230,7 +239,7 @@ async function fetchBitcoindFees() : Promise { rpc.batch(batchCall, (error: Error | null, response: BitcoindRpcBatchResponse[]) => { if (error) { - console.error({ message: 'Unable to fetch fee estimates from bitcoind: {error}', error }); + logger.error({ message: 'Unable to fetch fee estimates from bitcoind: {error}', error }); resolve(null); } else { targets.forEach((target, i) => { @@ -240,11 +249,11 @@ async function fetchBitcoindFees() : Promise { const satPerKB : number = feeRate * 1e8; data[target] = applyFeeMultiplier(satPerKB); } else { - console.error({ message: `Failed to fetch fee estimate from bitcoind for confirmation target ${target}: {errors}`, + logger.error({ message: `Failed to fetch fee estimate from bitcoind for confirmation target ${target}: {errors}`, errors: response[i].result?.errors}); } }); - console.debug({ message: 'Fetched data from bitcoind: {data}', data }); + logger.debug({ message: 'Fetched data from bitcoind: {data}', data }); resolve(data); } }); @@ -286,7 +295,7 @@ async function getEstimates() : Promise { let estimates: Estimates | undefined = cache.get(CACHE_KEY); if (estimates) { - console.info({ message: 'Got estimates from cache: ${estimates}', estimates }); + logger.info({ message: 'Got estimates from cache: ${estimates}', estimates }); return estimates; } @@ -309,7 +318,7 @@ async function getEstimates() : Promise { cache.set(CACHE_KEY, estimates); - console.info({ message: 'Got estimates: {estimates}', estimates }); + logger.info({ message: 'Got estimates: {estimates}', estimates }); return estimates; } @@ -403,7 +412,7 @@ function calculateFees(mempoolFeeEstimates: MempoolFeeEstimates, esploraFeeEstim // Get the minimum fee. If the mempool fee estimates are not available, use a default value of FEE_MINIMUM sat/vbyte as a safety net. const minFee = (mempoolFeeEstimates?.minimumFee ?? FEE_MINIMUM) * 1000; - console.debug({ message: 'Using minimum fee: {minFee}', minFee }); + logger.debug({ message: 'Using minimum fee: {minFee}', minFee }); // Return fees filterd to remove any that are lower than the determined minimum fee. if (minFee) { @@ -469,7 +478,7 @@ const Content = (props: { siteData: SiteData; estimates: Estimates }) => ( // Initialize the Express app. const app = new Hono(); -console.info(`Fee Estimates available at ${BASE_URL}/v1/fee-estimates`); +logger.info(`Fee Estimates available at ${BASE_URL}/v1/fee-estimates`); // Add a health/ready endpoint. app.get('/health/ready', async (c) => { @@ -482,7 +491,7 @@ app.get('/health/live', async (c) => { }); // Add middleware. -app.use('*', logger()) +app.use('*', honoLogger()) app.use('*', etag()) app.use('*', cors({ origin: '*', @@ -504,7 +513,7 @@ app.get('/', async (c) => { c.res.headers.set('Cache-Control', `public, max-age=${CACHE_STDTTL}`) } catch (error) { - console.error(error); + logger.error(error); estimates = { current_block_hash: null, fee_by_block_target: {} @@ -536,7 +545,7 @@ app.get('/v1/fee-estimates', async (c) => { return c.json(estimates); } catch (error) { - console.error(error); + logger.error(error); return c.text('Error fetching fee estimates', 500); } }); @@ -547,6 +556,6 @@ export default { } process.on('SIGINT', function() { - console.info({ message: "Caught interrupt signal. Exiting." }); + logger.info({ message: "Caught interrupt signal. Exiting." }); process.exit(); });