Commit 9eb36bd2798613e8435c9f03d43a50d8dab14e70

Authored by tangwang
1 parent 789edb14

add logs

offline_tasks/scripts/debug_utils.py
@@ -21,8 +21,9 @@ def setup_debug_logger(script_name, debug=False): @@ -21,8 +21,9 @@ def setup_debug_logger(script_name, debug=False):
21 """ 21 """
22 logger = logging.getLogger(script_name) 22 logger = logging.getLogger(script_name)
23 23
24 - # 清除已有的handlers  
25 - logger.handlers.clear() 24 + # 避免重复添加handler
  25 + if logger.handlers:
  26 + return logger
26 27
27 # 设置日志级别 28 # 设置日志级别
28 if debug: 29 if debug:
@@ -40,20 +41,20 @@ def setup_debug_logger(script_name, debug=False): @@ -40,20 +41,20 @@ def setup_debug_logger(script_name, debug=False):
40 console_handler.setFormatter(console_format) 41 console_handler.setFormatter(console_format)
41 logger.addHandler(console_handler) 42 logger.addHandler(console_handler)
42 43
43 - # 文件输出(如果开启debug) 44 + # 文件输出(总是输出到logs目录)
  45 + log_dir = os.path.join(os.path.dirname(os.path.dirname(__file__)), 'logs')
  46 + os.makedirs(log_dir, exist_ok=True)
  47 +
  48 + log_file = os.path.join(
  49 + log_dir,
  50 + f"{script_name}_{datetime.now().strftime('%Y%m%d')}.log"
  51 + )
  52 + file_handler = logging.FileHandler(log_file, encoding='utf-8')
  53 + file_handler.setLevel(logging.DEBUG)
  54 + file_handler.setFormatter(console_format)
  55 + logger.addHandler(file_handler)
  56 +
44 if debug: 57 if debug:
45 - log_dir = os.path.join(os.path.dirname(os.path.dirname(__file__)), 'logs', 'debug')  
46 - os.makedirs(log_dir, exist_ok=True)  
47 -  
48 - log_file = os.path.join(  
49 - log_dir,  
50 - f"{script_name}_{datetime.now().strftime('%Y%m%d_%H%M%S')}.log"  
51 - )  
52 - file_handler = logging.FileHandler(log_file, encoding='utf-8')  
53 - file_handler.setLevel(logging.DEBUG)  
54 - file_handler.setFormatter(console_format)  
55 - logger.addHandler(file_handler)  
56 -  
57 logger.debug(f"Debug log file: {log_file}") 58 logger.debug(f"Debug log file: {log_file}")
58 59
59 return logger 60 return logger
offline_tasks/scripts/i2i_item_behavior.py
@@ -56,6 +56,9 @@ parser.add_argument('--top_n', type=int, default=50, help='每个商品保留的 @@ -56,6 +56,9 @@ parser.add_argument('--top_n', type=int, default=50, help='每个商品保留的
56 parser.add_argument('--debug', action='store_true', help='开启debug模式') 56 parser.add_argument('--debug', action='store_true', help='开启debug模式')
57 args = parser.parse_args() 57 args = parser.parse_args()
58 58
  59 +# 初始化logger
  60 +logger = setup_logger()
  61 +
59 # 数据库连接配置 62 # 数据库连接配置
60 host = 'selectdb-cn-wuf3vsokg05-public.selectdbfe.rds.aliyuncs.com' 63 host = 'selectdb-cn-wuf3vsokg05-public.selectdbfe.rds.aliyuncs.com'
61 port = '9030' 64 port = '9030'
@@ -84,9 +87,14 @@ ORDER BY @@ -84,9 +87,14 @@ ORDER BY
84 se.create_time; 87 se.create_time;
85 """ 88 """
86 89
  90 +logger.info("="*80)
  91 +logger.info("I2I商品行为相似度计算开始")
  92 +logger.info("="*80)
  93 +logger.info(f"参数配置: lookback_days={args.lookback_days}, top_n={args.top_n}")
  94 +
87 if args.debug: 95 if args.debug:
88 - print(f"[DEBUG] 参数配置: lookback_days={args.lookback_days}, top_n={args.top_n}")  
89 - print(f"[DEBUG] 开始查询数据库...") 96 + logger.debug(f"[DEBUG] 参数配置: lookback_days={args.lookback_days}, top_n={args.top_n}")
  97 + logger.debug(f"[DEBUG] 开始查询数据库...")
90 98
91 # 执行 SQL 查询并将结果加载到 pandas DataFrame 99 # 执行 SQL 查询并将结果加载到 pandas DataFrame
92 df = pd.read_sql(sql_query, engine) 100 df = pd.read_sql(sql_query, engine)
@@ -95,10 +103,14 @@ df = pd.read_sql(sql_query, engine) @@ -95,10 +103,14 @@ df = pd.read_sql(sql_query, engine)
95 df['item_id'] = df['item_id'].astype(int) 103 df['item_id'] = df['item_id'].astype(int)
96 df['user_id'] = df['user_id'].astype(str) # user_id保持为字符串 104 df['user_id'] = df['user_id'].astype(str) # user_id保持为字符串
97 105
  106 +logger.info(f"数据库查询完成,共 {len(df)} 条记录")
  107 +logger.info(f"唯一用户数: {df['user_id'].nunique()}")
  108 +logger.info(f"唯一商品数: {df['item_id'].nunique()}")
  109 +
98 if args.debug: 110 if args.debug:
99 - print(f"[DEBUG] 查询完成,共 {len(df)} 条记录")  
100 - print(f"[DEBUG] 唯一用户数: {df['user_id'].nunique()}")  
101 - print(f"[DEBUG] 唯一商品数: {df['item_id'].nunique()}") 111 + logger.debug(f"[DEBUG] 查询完成,共 {len(df)} 条记录")
  112 + logger.debug(f"[DEBUG] 唯一用户数: {df['user_id'].nunique()}")
  113 + logger.debug(f"[DEBUG] 唯一商品数: {df['item_id'].nunique()}")
102 114
103 # 处理点击序列,计算共现关系 115 # 处理点击序列,计算共现关系
104 cooccur = defaultdict(lambda: defaultdict(int)) 116 cooccur = defaultdict(lambda: defaultdict(int))
@@ -122,8 +134,10 @@ for (user_id, date), group in df.groupby(['user_id', 'date']): @@ -122,8 +134,10 @@ for (user_id, date), group in df.groupby(['user_id', 'date']):
122 cooccur[item2][item1] += 1 134 cooccur[item2][item1] += 1
123 135
124 # 计算余弦相似度 136 # 计算余弦相似度
  137 +logger.info("开始计算商品相似度...")
  138 +
125 if args.debug: 139 if args.debug:
126 - print(f"[DEBUG] 开始计算相似度...") 140 + logger.debug(f"[DEBUG] 开始计算相似度...")
127 141
128 result = {} 142 result = {}
129 for item1 in cooccur: 143 for item1 in cooccur:
@@ -138,8 +152,10 @@ for item1 in cooccur: @@ -138,8 +152,10 @@ for item1 in cooccur:
138 # 只保留top_n个相似商品 152 # 只保留top_n个相似商品
139 result[item1] = sim_scores[:args.top_n] 153 result[item1] = sim_scores[:args.top_n]
140 154
  155 +logger.info(f"相似度计算完成,共 {len(result)} 个商品有相似推荐")
  156 +
141 if args.debug: 157 if args.debug:
142 - print(f"[DEBUG] 相似度计算完成,共 {len(result)} 个商品有相似推荐") 158 + logger.debug(f"[DEBUG] 相似度计算完成,共 {len(result)} 个商品有相似推荐")
143 159
144 # 创建item_id到name的映射 160 # 创建item_id到name的映射
145 item_name_map = dict(zip(df['item_id'], df['item_name'])) 161 item_name_map = dict(zip(df['item_id'], df['item_name']))
@@ -151,8 +167,10 @@ os.makedirs(output_dir, exist_ok=True) @@ -151,8 +167,10 @@ os.makedirs(output_dir, exist_ok=True)
151 output_file = os.path.join(output_dir, f'i2i_item_behavior_{date_str}.txt') 167 output_file = os.path.join(output_dir, f'i2i_item_behavior_{date_str}.txt')
152 168
153 # 输出相似商品到文件 169 # 输出相似商品到文件
  170 +logger.info(f"开始写入输出文件: {output_file}")
  171 +
154 if args.debug: 172 if args.debug:
155 - print(f"[DEBUG] 开始写入文件: {output_file}") 173 + logger.debug(f"[DEBUG] 开始写入文件: {output_file}")
156 174
157 with open(output_file, 'w', encoding='utf-8') as f: 175 with open(output_file, 'w', encoding='utf-8') as f:
158 for item_id, sims in sorted(result.items()): 176 for item_id, sims in sorted(result.items()):
@@ -161,16 +179,32 @@ with open(output_file, 'w', encoding='utf-8') as f: @@ -161,16 +179,32 @@ with open(output_file, 'w', encoding='utf-8') as f:
161 sim_str = ','.join([f'{sim_id}:{score:.4f}' for sim_id, score in sims]) 179 sim_str = ','.join([f'{sim_id}:{score:.4f}' for sim_id, score in sims])
162 f.write(f'{item_id}\t{item_name}\t{sim_str}\n') 180 f.write(f'{item_id}\t{item_name}\t{sim_str}\n')
163 181
164 -print(f"✓ Item相似度计算完成")  
165 -print(f" - 输出文件: {output_file}")  
166 -print(f" - 商品数: {len(result)}")  
167 -if result:  
168 - avg_sims = sum(len(sims) for sims in result.values()) / len(result)  
169 - print(f" - 平均相似商品数: {avg_sims:.1f}") 182 +logger.info(f"输出文件写入完成: {output_file}")
  183 +
  184 +# 统计信息
  185 +total_similarity_pairs = sum(len(sims) for sims in result.values())
  186 +avg_sims = total_similarity_pairs / len(result) if result else 0
  187 +
  188 +logger.info("="*80)
  189 +logger.info("I2I商品行为相似度计算 - 关键统计信息")
  190 +logger.info("="*80)
  191 +logger.info(f"📊 数据概览:")
  192 +logger.info(f" - 总行为记录数: {len(df):,}")
  193 +logger.info(f" - 唯一用户数: {df['user_id'].nunique():,}")
  194 +logger.info(f" - 唯一商品数: {df['item_id'].nunique():,}")
  195 +logger.info(f" - 有相似度的商品数: {len(result):,}")
  196 +logger.info(f" - 总相似度对数量: {total_similarity_pairs:,}")
  197 +logger.info(f" - 平均每商品相似数: {avg_sims:.1f}")
  198 +
  199 +logger.info(f"📁 输出文件:")
  200 +logger.info(f" - 输出文件: {output_file}")
  201 +
  202 +logger.info(f"✅ I2I商品行为相似度计算完成")
  203 +logger.info("="*80)
170 204
171 # 如果启用debug模式,保存可读格式 205 # 如果启用debug模式,保存可读格式
172 if args.debug and result: 206 if args.debug and result:
173 - print("[DEBUG] 保存可读格式文件...") 207 + logger.debug("[DEBUG] 保存可读格式文件...")
174 208
175 # 准备name_mappings 209 # 准备name_mappings
176 name_mappings = { 210 name_mappings = {
offline_tasks/scripts/load_index_to_redis.py
@@ -10,11 +10,41 @@ import sys @@ -10,11 +10,41 @@ import sys
10 from datetime import datetime 10 from datetime import datetime
11 from config.offline_config import REDIS_CONFIG, OUTPUT_DIR 11 from config.offline_config import REDIS_CONFIG, OUTPUT_DIR
12 12
13 -logging.basicConfig(  
14 - level=logging.INFO,  
15 - format='%(asctime)s - %(levelname)s - %(message)s'  
16 -)  
17 -logger = logging.getLogger(__name__) 13 +def setup_logger():
  14 + """设置logger配置"""
  15 + # 创建logs目录
  16 + logs_dir = 'logs'
  17 + os.makedirs(logs_dir, exist_ok=True)
  18 +
  19 + # 创建logger
  20 + logger = logging.getLogger('load_index_to_redis')
  21 + logger.setLevel(logging.INFO)
  22 +
  23 + # 避免重复添加handler
  24 + if logger.handlers:
  25 + return logger
  26 +
  27 + # 创建文件handler
  28 + log_file = os.path.join(logs_dir, f'load_index_to_redis_{datetime.now().strftime("%Y%m%d")}.log')
  29 + file_handler = logging.FileHandler(log_file, encoding='utf-8')
  30 + file_handler.setLevel(logging.INFO)
  31 +
  32 + # 创建控制台handler
  33 + console_handler = logging.StreamHandler()
  34 + console_handler.setLevel(logging.INFO)
  35 +
  36 + # 创建formatter
  37 + formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
  38 + file_handler.setFormatter(formatter)
  39 + console_handler.setFormatter(formatter)
  40 +
  41 + # 添加handler到logger
  42 + logger.addHandler(file_handler)
  43 + logger.addHandler(console_handler)
  44 +
  45 + return logger
  46 +
  47 +logger = setup_logger()
18 48
19 49
20 def load_index_file(file_path, redis_client, key_prefix, expire_seconds=None): 50 def load_index_file(file_path, redis_client, key_prefix, expire_seconds=None):