Skip to content

Commit

Permalink
Feature/logging (#54)
Browse files Browse the repository at this point in the history
* Replace print with logging

* log
  • Loading branch information
hanchiang authored Aug 31, 2023
1 parent 0054fa3 commit 04391cd
Show file tree
Hide file tree
Showing 19 changed files with 103 additions and 47 deletions.
7 changes: 5 additions & 2 deletions src/db/redis.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import logging

import redis.asyncio as redis

from src.config import config

logger = logging.getLogger('Redis')
class Redis:
redis: redis.Redis

Expand All @@ -11,11 +14,11 @@ def get_client():

@staticmethod
async def start_redis():
print('starting redis')
logger.info('starting redis')
host = config.get_redis_host()
Redis.redis = await redis.Redis(host=host, port=config.get_redis_port(), db=config.get_redis_db())

@staticmethod
async def stop_redis():
print('stopping redis')
logger.info('stopping redis')
await Redis.redis.close()
7 changes: 5 additions & 2 deletions src/dependencies.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import logging

from src.service.barchart import BarchartService
from src.service.crypto_sentiment import CryptoSentimentService
from src.service.stocks_sentiment import StocksSentimentService
Expand All @@ -11,6 +13,7 @@
from src.third_party_service.vix_central import ThirdPartyVixCentralService
from src.service.vix_central import VixCentralService

logger = logging.getLogger('Dependencies')
class Dependencies:
is_initialised: bool = False

Expand Down Expand Up @@ -56,9 +59,9 @@ async def build():
Dependencies.crypto_sentiment_service = CryptoSentimentService()

Dependencies.is_initialised = True
print('Dependencies built')
logger.info('Dependencies built')
else:
print('Dependencies has already been initialised')
logger.info('Dependencies has already been initialised')

@staticmethod
async def cleanup():
Expand Down
10 changes: 7 additions & 3 deletions src/event/event_emitter.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
import logging
from pyee.asyncio import AsyncIOEventEmitter

from src.notification_destination import telegram_notification
from src.type.market_data_type import MarketDataType
from src.util.my_telegram import escape_markdown
from src.util.exception import get_exception_message

async_ee = AsyncIOEventEmitter()

logger = logging.getLogger('Event emitter')
@async_ee.on('error')
async def on_error(message):
print(f"event emitter error: {message}")
logger.error(f"event emitter error: {message}")
await telegram_notification.send_message_to_admin(escape_markdown(str(f'event emitter error: {message}')), market_data_type=MarketDataType.STOCKS)

@async_ee.on('send_to_telegram')
Expand All @@ -17,10 +20,11 @@ async def send_to_telegram_handler(*args, **kwargs):
channel = kwargs['channel']
message = kwargs['message']
market_data_type = kwargs['market_data_type']
raise RuntimeError("oops error")
res = await telegram_notification.send_message_to_channel(message=message, chat_id=channel, market_data_type=market_data_type)
if res:
telegram_notification.print_telegram_message(res)
except Exception as e:
print(e)
logger.error(f"{get_exception_message(e)}")
market_data_type = kwargs['market_data_type'] or MarketDataType.STOCKS
await telegram_notification.send_message_to_admin(escape_markdown(str(e)), market_data_type=market_data_type)
await telegram_notification.send_message_to_admin(f"{escape_markdown(str(e))}, stack: {escape_markdown(tb)}", market_data_type=market_data_type)
11 changes: 6 additions & 5 deletions src/job/crypto/crypto.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import asyncio
import logging

from src.job.crypto.chain_analysis_message_sender import ChainAnalysisMessageSender
from src.job.crypto.messari_message_sender import MessariMessageSender
Expand All @@ -10,6 +11,7 @@

# TODO: test

logger = logging.getLogger('Crypto notification job')
class CryptoNotificationJob(JobWrapper):
# run at 8.45am, 4.15pm
def should_run(self) -> bool:
Expand All @@ -31,15 +33,14 @@ def should_run(self) -> bool:
local = local.replace(hour=local_hour_int, minute=local_minute_int)
delta = now - local
should_run = abs(delta.total_seconds()) <= config.get_job_delay_tolerance_second()
logger.info(
f'local time: {local}, current time: {now}, local hour to run: {local_hour_int}, local minute to run: {local_minute_int}, current hour {now.hour}, current minute: {now.minute}, delta second: {delta.total_seconds()}, should run: {should_run}')
if should_run:
print(
f'local time: {local}, current time: {now}, local hour to run: {local_hour_int}, local minute to run: {local_minute_int}, current hour {now.hour}, current minute: {now.minute}, delta second: {delta.total_seconds()}, should run: {should_run}')
return should_run

print(
f'local time: {local}, current time: {now}, local hour to run: {local_hour_int}, local minute to run: {local_minute_int}, current hour {now.hour}, current minute: {now.minute}, delta second: {delta.total_seconds()}, should run: {should_run}')
return should_run


@property
def message_senders(self):
return [MessariMessageSender(), ChainAnalysisMessageSender(), SentimentMessageSender()]
Expand All @@ -53,4 +54,4 @@ def market_data_type(self):
loop = asyncio.get_event_loop()
job = CryptoNotificationJob()
data = asyncio.run(job.start())
print(data)
logger.info(data)
9 changes: 5 additions & 4 deletions src/job/job_wrapper.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import argparse
import traceback
import logging
from abc import ABC, abstractmethod
from typing import List

Expand All @@ -10,10 +10,12 @@
from src.notification_destination.telegram_notification import send_message_to_channel, \
market_data_type_to_admin_chat_id, init_telegram_bots
from src.util.context_manager import TimeTrackerContext
from src.util.exception import get_exception_message
from src.util.my_telegram import format_messages_to_telegram, escape_markdown
from src.type.market_data_type import MarketDataType


logger = logging.getLogger('Job wrapper')
class JobWrapper(ABC):
async def start(self):
parser = argparse.ArgumentParser(description='Sends daily stock data notification to telegram')
Expand Down Expand Up @@ -52,9 +54,8 @@ async def start(self):
return res

except Exception as e:
tb = traceback.format_exc()
print(f"{self.__class__.__name__} exception: {e}, stack: {tb}")
messages.append(f"{escape_markdown(str(e))}, stack: {tb}")
logger.error(get_exception_message(e, cls=self.__class__.__name__))
messages.append(f"{get_exception_message(e, cls=self.__class__.__name__, should_escape_markdown=True)}")
message = format_messages_to_telegram(messages)
await send_message_to_channel(message=message, chat_id=market_data_type_to_admin_chat_id[self.market_data_type],
market_data_type=self.market_data_type)
Expand Down
11 changes: 6 additions & 5 deletions src/job/message_sender_wrapper.py
Original file line number Diff line number Diff line change
@@ -1,19 +1,21 @@
import traceback
import logging
from abc import ABC, abstractmethod
from typing import List

from src.notification_destination.telegram_notification import send_message_to_channel, \
market_data_type_to_admin_chat_id, market_data_type_to_chat_id
from src.util.exception import get_exception_message
from src.util.my_telegram import escape_markdown, format_messages_to_telegram


logger = logging.getLogger('Message sender wrapper')
class MessageSenderWrapper(ABC):
async def start(self):
try:
messages = await self.format_message()

if messages is None or len(messages) == 0:
print(f"No message to send for market data type: {self.market_data_type}, data source: {self.data_source}")
logger.warning(f"No message to send for market data type: {self.market_data_type}, data source: {self.data_source}")
return

telegram_message = format_messages_to_telegram(messages)
Expand All @@ -22,9 +24,8 @@ async def start(self):
market_data_type=self.market_data_type)
return res
except Exception as e:
tb = traceback.format_exc()
print(f"{self.__class__.__name__} exception: {e}, stack: {tb}")
messages = [f"{escape_markdown(str(e))}, stack: {tb}"]
logger.error(get_exception_message(e, cls=self.__class__.__name__))
messages = [f"{get_exception_message(e, cls=self.__class__.__name__, should_escape_markdown=True)}"]
message = format_messages_to_telegram(messages)
await send_message_to_channel(message=message, chat_id=market_data_type_to_admin_chat_id[self.market_data_type],
market_data_type=self.market_data_type)
Expand Down
5 changes: 4 additions & 1 deletion src/job/stocks/sentiment_message_sender.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
import logging

from src.dependencies import Dependencies
from src.job.message_sender_wrapper import MessageSenderWrapper
from src.type.sentiment import FearGreedResult
from src.type.market_data_type import MarketDataType
from src.util.my_telegram import escape_markdown
import src.util.date_util as date_util

logger = logging.getLogger('Stocks sentiment message sender')
class StocksSentimentMessageSender(MessageSenderWrapper):
@property
def data_source(self):
Expand All @@ -29,7 +32,7 @@ async def format_message(self):
if message is not None:
messages.append(message)

print(messages)
logger.info(messages)

return messages

Expand Down
6 changes: 4 additions & 2 deletions src/job/stocks/stocks.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import asyncio
import logging

from src.job.job_wrapper import JobWrapper
from src.job.stocks.sentiment_message_sender import StocksSentimentMessageSender
Expand All @@ -9,6 +10,7 @@
from src.type.market_data_type import MarketDataType

# TODO: test
logger = logging.getLogger('Stocks notification job')
class StocksNotificationJob(JobWrapper):
# run at 8.45am
def should_run(self) -> bool:
Expand All @@ -22,7 +24,7 @@ def should_run(self) -> bool:
delta = now - local

should_run = abs(delta.total_seconds()) <= config.get_job_delay_tolerance_second()
print(
logger.info(
f'local time: {local}, current time: {now}, local hour to run: {config.get_stocks_job_start_local_hour()}, local minute to run: {config.get_stocks_job_start_local_minute()}, current hour {now.hour}, current minute: {now.minute}, delta second: {delta.total_seconds()}, should run: {should_run}')
return should_run

Expand All @@ -43,4 +45,4 @@ def market_data_type(self):
loop = asyncio.get_event_loop()
job = StocksNotificationJob()
data = asyncio.run(job.start())
print(data)
logger.info(data)
3 changes: 3 additions & 0 deletions src/job/stocks/tradingview_message_sender.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import datetime
import logging
from typing import List

from src.dependencies import Dependencies
Expand All @@ -13,6 +14,7 @@
from src.util.sleep import sleep


logger = logging.getLogger('Trading view message sender')
class TradingViewMessageSender(MessageSenderWrapper):
@property
def data_source(self):
Expand Down Expand Up @@ -40,6 +42,7 @@ async def format_message(self):
most_recent_day = get_most_recent_non_weekend_or_today(now - datetime.timedelta(days=1))
time_diff = abs(int(most_recent_day.timestamp()) - tradingview_stocks_data.score)
if not config.get_is_testing_telegram() and time_diff > 86400:
logger.info(f'Skip formatting message. is testing telegram: {config.get_is_testing_telegram()}, time difference: {time_diff}')
return messages

tradingview_economy_indicator_data = await self.tradingview_service.get_tradingview_daily_stocks_data(
Expand Down
17 changes: 10 additions & 7 deletions src/notification_destination/telegram_notification.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import logging

import telegram
import src.config.config as config
from src.type.market_data_type import MarketDataType
from src.util.exception import get_exception_message
from src.util.my_telegram import escape_markdown

# TODO: Clean up
Expand All @@ -16,9 +19,11 @@
market_data_type_to_admin_chat_id = {}
market_data_type_to_chat_id = {}

logger = logging.getLogger('Telegram notification')

def init_telegram_bots():
global stocks_bot, stocks_admin_bot, stocks_dev_bot, crypto_bot, crypto_admin_bot, crypto_dev_bot
print('Initialising telegram bots')
logger.info('Initialising telegram bots')
stocks_bot = telegram.Bot(token=config.get_telegram_stocks_bot_token())
stocks_admin_bot = telegram.Bot(token=config.get_telegram_stocks_admin_bot_token())
stocks_dev_bot = telegram.Bot(token=config.get_telegram_stocks_dev_bot_token())
Expand All @@ -45,15 +50,13 @@ def init_telegram_bots():





async def send_message_to_channel(message: str, chat_id, market_data_type: MarketDataType):
if config.get_disable_telegram():
print('Telegram is disabled')
logger.info('Telegram is disabled')
return

if market_data_type is None:
print('market_data_type is not passed in')
logger.warning('market_data_type is not passed in')
return

if config.get_is_testing_telegram() or config.get_simulate_tradingview_traffic():
Expand All @@ -63,7 +66,7 @@ async def send_message_to_channel(message: str, chat_id, market_data_type: Marke
res = await chat_id_to_telegram_client[chat_id].send_message(chat_id, text=message, parse_mode='MarkdownV2')
return res
except Exception as e:
print(e)
logger.error(get_exception_message(e))
await chat_id_to_telegram_client[chat_id].send_message(chat_id, text=escape_markdown(str(e)), parse_mode='MarkdownV2')

async def send_message_to_admin(message: str, market_data_type: MarketDataType):
Expand All @@ -83,4 +86,4 @@ def get_dev_channel_id_from_market_data_type(market_data_type: MarketDataType):
return config.get_telegram_stocks_dev_id()

def print_telegram_message(res: telegram.Message):
print(f"Sent to {res.chat.title} {res.chat.type} at {res.date}. Message id {res.id}")
logging.info(f"Sent to {res.chat.title} {res.chat.type} at {res.date}. Message id {res.id}")
13 changes: 8 additions & 5 deletions src/router/tradingview/tradingview.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import asyncio
import json
import logging

from fastapi import APIRouter, Request

Expand All @@ -9,11 +10,13 @@
from src.type.market_data_type import MarketDataType
from src.type.trading_view import TradingViewDataType
from src.util.date_util import get_current_date
from src.util.exception import get_exception_message
from src.util.my_telegram import format_messages_to_telegram, escape_markdown
from src.util.sleep import sleep

router = APIRouter(prefix="/tradingview")

logger = logging.getLogger('Trading view')
@router.post("/daily-stocks")
async def tradingview_daily_stocks_data(request: Request):
# for economy_indicator type, there is no ema20s, volumes
Expand All @@ -27,10 +30,10 @@ async def tradingview_daily_stocks_data(request: Request):
try:
body = await request.json()
filtered_body = filter_tradingview_request_body(body)
print(filtered_body)
logger.info(filtered_body)
except Exception as e:
print(e)
messages.append(f"JSON body error: {escape_markdown(str(e))}")
logger.error(get_exception_message(e))
messages.append(f"JSON body error: {get_exception_message(e, should_escape_markdown=True)}")
message = format_messages_to_telegram(messages)
async_ee.emit('send_to_telegram', message=message, channel=config.get_telegram_stocks_admin_id(), market_data_type=MarketDataType.STOCKS)
return {"data": "OK"}
Expand Down Expand Up @@ -80,7 +83,7 @@ async def tradingview_daily_stocks_data(request: Request):

save_message = f'Successfully saved trading view data for type: *{escape_markdown(filtered_body.get("type"))}* at *{escape_markdown(str(now))}*, key: *{escape_markdown(key)}*, score: *{timestamp}*, days to store: *{config.get_trading_view_days_to_store()}*'
messages.append(save_message)
print(f'Successfully saved trading view data for {str(now)}, key: {key}, score: {timestamp}, days to store: {config.get_trading_view_days_to_store()}, data: {json_data}')
logger.info(f'Successfully saved trading view data for {str(now)}, key: {key}, score: {timestamp}, days to store: {config.get_trading_view_days_to_store()}, data: {json_data}')
# sleep for a bit, telegram client will timeout if concurrent requests come in
# await sleep()
async_ee.emit('send_to_telegram', message=format_messages_to_telegram(messages), channel=config.get_telegram_stocks_admin_id(), market_data_type=MarketDataType.STOCKS)
Expand All @@ -93,7 +96,7 @@ async def tradingview_daily_stocks_data(request: Request):

async def reset_is_testing_telegram(original_value: str, delay: int = 3):
await asyncio.sleep(delay)
print(f'Set is_telegram_telegram to original value {original_value} after sleeping for {delay} seconds')
logger.info(f'Set is_telegram_telegram to original value {original_value} after sleeping for {delay} seconds')
config.set_is_testing_telegram(original_value)

def filter_tradingview_request_body(body: dict) -> dict:
Expand Down
Loading

0 comments on commit 04391cd

Please sign in to comment.