Logging with loguru (#708)

* logging

* requirements

* add loguru dependency

* restore it

* add loguru

* set log level in .env file

* remove service fee print

* set log level

* more logging

* more logging

* more logging

* pyament.checking_id

* fix
This commit is contained in:
calle
2022-07-07 14:30:16 +02:00
committed by GitHub
parent 847fd18796
commit 089313f613
40 changed files with 202 additions and 81 deletions
+7 -2
View File
@@ -7,6 +7,9 @@ from lnurl import encode as lnurl_encode # type: ignore
from typing import List, NamedTuple, Optional, Dict
from sqlite3 import Row
from pydantic import BaseModel
from loguru import logger
from lnbits.settings import WALLET
@@ -142,10 +145,12 @@ class Payment(BaseModel):
status = await WALLET.get_invoice_status(self.checking_id)
if self.is_out and status.failed:
print(f" - deleting outgoing failed payment {self.checking_id}: {status}")
logger.info(
f" - deleting outgoing failed payment {self.checking_id}: {status}"
)
await self.delete()
elif not status.pending:
print(
logger.info(
f" - marking '{'in' if self.is_in else 'out'}' {self.checking_id} as not pending anymore: {status}"
)
await self.set_pending(status.pending)
+18 -5
View File
@@ -3,6 +3,9 @@ import json
from binascii import unhexlify
from io import BytesIO
from typing import Dict, Optional, Tuple
from loguru import logger
from urllib.parse import parse_qs, urlparse
import httpx
@@ -120,6 +123,7 @@ async def pay_invoice(
# check_internal() returns the checking_id of the invoice we're waiting for
internal_checking_id = await check_internal(invoice.payment_hash, conn=conn)
if internal_checking_id:
logger.debug(f"creating temporary internal payment with id {internal_id}")
# create a new payment from this wallet
await create_payment(
checking_id=internal_id,
@@ -129,6 +133,7 @@ async def pay_invoice(
**payment_kwargs,
)
else:
logger.debug(f"creating temporary payment with id {temp_id}")
# create a temporary payment here so we can check if
# the balance is enough in the next step
await create_payment(
@@ -142,6 +147,7 @@ async def pay_invoice(
wallet = await get_wallet(wallet_id, conn=conn)
assert wallet
if wallet.balance_msat < 0:
logger.debug("balance is too low, deleting temporary payment")
if not internal_checking_id and wallet.balance_msat > -fee_reserve_msat:
raise PaymentFailure(
f"You must reserve at least 1% ({round(fee_reserve_msat/1000)} sat) to cover potential routing fees."
@@ -149,6 +155,7 @@ async def pay_invoice(
raise PermissionError("Insufficient balance.")
if internal_checking_id:
logger.debug(f"marking temporary payment as not pending {internal_checking_id}")
# mark the invoice from the other side as not pending anymore
# so the other side only has access to his new money when we are sure
# the payer has enough to deduct from
@@ -163,11 +170,14 @@ async def pay_invoice(
await internal_invoice_queue.put(internal_checking_id)
else:
logger.debug(f"backend: sending payment {temp_id}")
# actually pay the external invoice
payment: PaymentResponse = await WALLET.pay_invoice(
payment_request, fee_reserve_msat
)
logger.debug(f"backend: pay_invoice finished {temp_id}")
if payment.checking_id:
logger.debug(f"creating final payment {payment.checking_id}")
async with db.connect() as conn:
await create_payment(
checking_id=payment.checking_id,
@@ -177,15 +187,18 @@ async def pay_invoice(
conn=conn,
**payment_kwargs,
)
logger.debug(f"deleting temporary payment {temp_id}")
await delete_payment(temp_id, conn=conn)
else:
logger.debug(f"backend payment failed, no checking_id {temp_id}")
async with db.connect() as conn:
logger.debug(f"deleting temporary payment {temp_id}")
await delete_payment(temp_id, conn=conn)
raise PaymentFailure(
payment.error_message
or "Payment failed, but backend didn't give us an error message."
)
logger.debug(f"payment successful {payment.checking_id}")
return invoice.payment_hash
@@ -216,7 +229,7 @@ async def redeem_lnurl_withdraw(
conn=conn,
)
except:
print(
logger.warn(
f"failed to create invoice on redeem_lnurl_withdraw from {lnurl}. params: {res}"
)
return None
@@ -325,11 +338,11 @@ async def check_invoice_status(
if not payment.pending:
return status
if payment.is_out and status.failed:
print(f" - deleting outgoing failed payment {payment.checking_id}: {status}")
logger.info(f"deleting outgoing failed payment {payment.checking_id}: {status}")
await payment.delete()
elif not status.pending:
print(
f" - marking '{'in' if payment.is_in else 'out'}' {payment.checking_id} as not pending anymore: {status}"
logger.info(
f"marking '{'in' if payment.is_in else 'out'}' {payment.checking_id} as not pending anymore: {status}"
)
await payment.set_pending(status.pending)
return status
+5 -2
View File
@@ -2,6 +2,8 @@ import asyncio
import httpx
from typing import List
from loguru import logger
from lnbits.tasks import register_invoice_listener
from . import db
@@ -20,7 +22,7 @@ async def register_task_listeners():
async def wait_for_paid_invoices(invoice_paid_queue: asyncio.Queue):
while True:
payment = await invoice_paid_queue.get()
logger.debug("received invoice paid event")
# send information to sse channel
await dispatch_invoice_listener(payment)
@@ -44,7 +46,7 @@ async def dispatch_invoice_listener(payment: Payment):
try:
send_channel.put_nowait(payment)
except asyncio.QueueFull:
print("removing sse listener", send_channel)
logger.debug("removing sse listener", send_channel)
api_invoice_listeners.remove(send_channel)
@@ -52,6 +54,7 @@ async def dispatch_webhook(payment: Payment):
async with httpx.AsyncClient() as client:
data = payment.dict()
try:
logger.debug("sending webhook", payment.webhook)
r = await client.post(payment.webhook, json=data, timeout=40)
await mark_webhook_sent(payment, r.status_code)
except (httpx.ConnectError, httpx.RequestError):
+6 -2
View File
@@ -7,6 +7,9 @@ from typing import Dict, List, Optional, Union
from urllib.parse import ParseResult, parse_qs, urlencode, urlparse, urlunparse
import httpx
from loguru import logger
from fastapi import Header, Query, Request
from fastapi.exceptions import HTTPException
from fastapi.param_functions import Depends
@@ -347,7 +350,7 @@ async def subscribe(request: Request, wallet: Wallet):
payment_queue: asyncio.Queue[Payment] = asyncio.Queue(0)
print("adding sse listener", payment_queue)
logger.debug("adding sse listener", payment_queue)
api_invoice_listeners.append(payment_queue)
send_queue: asyncio.Queue[tuple[str, Payment]] = asyncio.Queue(0)
@@ -356,6 +359,7 @@ async def subscribe(request: Request, wallet: Wallet):
while True:
payment: Payment = await payment_queue.get()
if payment.wallet_id == this_wallet_id:
logger.debug("payment receieved", payment)
await send_queue.put(("payment-received", payment))
asyncio.create_task(payment_received())
@@ -391,7 +395,7 @@ async def api_payment(payment_hash, X_Api_Key: Optional[str] = Header(None)):
wallet = None
try:
if X_Api_Key.extra:
print("No key")
logger.warn("No key")
except:
wallet = await get_wallet_for_key(X_Api_Key)
payment = await get_standalone_payment(payment_hash)
+10 -1
View File
@@ -10,6 +10,8 @@ from fastapi.routing import APIRouter
from pydantic.types import UUID4
from starlette.responses import HTMLResponse, JSONResponse
from loguru import logger
from lnbits.core import db
from lnbits.core.models import User
from lnbits.decorators import check_user_exists
@@ -66,10 +68,12 @@ async def extensions(
)
if extension_to_enable:
logger.info(f"Enabling extension: {extension_to_enable} for user {user.id}")
await update_user_extension(
user_id=user.id, extension=extension_to_enable, active=True
)
elif extension_to_disable:
logger.info(f"Disabling extension: {extension_to_disable} for user {user.id}")
await update_user_extension(
user_id=user.id, extension=extension_to_disable, active=False
)
@@ -109,6 +113,7 @@ async def wallet(
if not user_id:
user = await get_user((await create_account()).id)
logger.info(f"Created new account for user {user.id}")
else:
user = await get_user(user_id)
if not user:
@@ -126,12 +131,16 @@ async def wallet(
wallet = user.wallets[0]
else:
wallet = await create_wallet(user_id=user.id, wallet_name=wallet_name)
logger.info(
f"Created new wallet {wallet_name if wallet_name else '(no name)'} for user {user.id}"
)
return RedirectResponse(
f"/wallet?usr={user.id}&wal={wallet.id}",
status_code=status.HTTP_307_TEMPORARY_REDIRECT,
)
logger.info(f"Access wallet {wallet_name} of user {user.id}")
wallet = user.get_wallet(wallet_id)
if not wallet:
return template_renderer().TemplateResponse(
@@ -202,13 +211,13 @@ async def lnurl_full_withdraw_callback(request: Request):
async def deletewallet(request: Request, wal: str = Query(...), usr: str = Query(...)):
user = await get_user(usr)
user_wallet_ids = [u.id for u in user.wallets]
print("USR", user_wallet_ids)
if wal not in user_wallet_ids:
raise HTTPException(HTTPStatus.FORBIDDEN, "Not your wallet.")
else:
await delete_wallet(user_id=user.id, wallet_id=wal)
user_wallet_ids.remove(wal)
logger.debug("Deleted wallet {wal} of user {user.id}")
if user_wallet_ids:
return RedirectResponse(
+3 -1
View File
@@ -7,6 +7,8 @@ from fastapi import HTTPException
from starlette.requests import Request
from starlette.responses import HTMLResponse
from loguru import logger
from lnbits import bolt11
from .. import core_app
@@ -45,7 +47,7 @@ async def api_public_payment_longpolling(payment_hash):
payment_queue = asyncio.Queue(0)
print("adding standalone invoice listener", payment_hash, payment_queue)
logger.debug("adding standalone invoice listener", payment_hash, payment_queue)
api_invoice_listeners.append(payment_queue)
response = None