Commit 9eb36bd2798613e8435c9f03d43a50d8dab14e70
1 parent
789edb14
add logs
Showing
3 changed files
with
100 additions
and
35 deletions
Show diff stats
offline_tasks/scripts/debug_utils.py
| ... | ... | @@ -21,8 +21,9 @@ def setup_debug_logger(script_name, debug=False): |
| 21 | 21 | """ |
| 22 | 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 | 29 | if debug: |
| ... | ... | @@ -40,20 +41,20 @@ def setup_debug_logger(script_name, debug=False): |
| 40 | 41 | console_handler.setFormatter(console_format) |
| 41 | 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 | 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 | 58 | logger.debug(f"Debug log file: {log_file}") |
| 58 | 59 | |
| 59 | 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 | 56 | parser.add_argument('--debug', action='store_true', help='开启debug模式') |
| 57 | 57 | args = parser.parse_args() |
| 58 | 58 | |
| 59 | +# 初始化logger | |
| 60 | +logger = setup_logger() | |
| 61 | + | |
| 59 | 62 | # 数据库连接配置 |
| 60 | 63 | host = 'selectdb-cn-wuf3vsokg05-public.selectdbfe.rds.aliyuncs.com' |
| 61 | 64 | port = '9030' |
| ... | ... | @@ -84,9 +87,14 @@ ORDER BY |
| 84 | 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 | 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 | 99 | # 执行 SQL 查询并将结果加载到 pandas DataFrame |
| 92 | 100 | df = pd.read_sql(sql_query, engine) |
| ... | ... | @@ -95,10 +103,14 @@ df = pd.read_sql(sql_query, engine) |
| 95 | 103 | df['item_id'] = df['item_id'].astype(int) |
| 96 | 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 | 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 | 116 | cooccur = defaultdict(lambda: defaultdict(int)) |
| ... | ... | @@ -122,8 +134,10 @@ for (user_id, date), group in df.groupby(['user_id', 'date']): |
| 122 | 134 | cooccur[item2][item1] += 1 |
| 123 | 135 | |
| 124 | 136 | # 计算余弦相似度 |
| 137 | +logger.info("开始计算商品相似度...") | |
| 138 | + | |
| 125 | 139 | if args.debug: |
| 126 | - print(f"[DEBUG] 开始计算相似度...") | |
| 140 | + logger.debug(f"[DEBUG] 开始计算相似度...") | |
| 127 | 141 | |
| 128 | 142 | result = {} |
| 129 | 143 | for item1 in cooccur: |
| ... | ... | @@ -138,8 +152,10 @@ for item1 in cooccur: |
| 138 | 152 | # 只保留top_n个相似商品 |
| 139 | 153 | result[item1] = sim_scores[:args.top_n] |
| 140 | 154 | |
| 155 | +logger.info(f"相似度计算完成,共 {len(result)} 个商品有相似推荐") | |
| 156 | + | |
| 141 | 157 | if args.debug: |
| 142 | - print(f"[DEBUG] 相似度计算完成,共 {len(result)} 个商品有相似推荐") | |
| 158 | + logger.debug(f"[DEBUG] 相似度计算完成,共 {len(result)} 个商品有相似推荐") | |
| 143 | 159 | |
| 144 | 160 | # 创建item_id到name的映射 |
| 145 | 161 | item_name_map = dict(zip(df['item_id'], df['item_name'])) |
| ... | ... | @@ -151,8 +167,10 @@ os.makedirs(output_dir, exist_ok=True) |
| 151 | 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 | 172 | if args.debug: |
| 155 | - print(f"[DEBUG] 开始写入文件: {output_file}") | |
| 173 | + logger.debug(f"[DEBUG] 开始写入文件: {output_file}") | |
| 156 | 174 | |
| 157 | 175 | with open(output_file, 'w', encoding='utf-8') as f: |
| 158 | 176 | for item_id, sims in sorted(result.items()): |
| ... | ... | @@ -161,16 +179,32 @@ with open(output_file, 'w', encoding='utf-8') as f: |
| 161 | 179 | sim_str = ','.join([f'{sim_id}:{score:.4f}' for sim_id, score in sims]) |
| 162 | 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 | 205 | # 如果启用debug模式,保存可读格式 |
| 172 | 206 | if args.debug and result: |
| 173 | - print("[DEBUG] 保存可读格式文件...") | |
| 207 | + logger.debug("[DEBUG] 保存可读格式文件...") | |
| 174 | 208 | |
| 175 | 209 | # 准备name_mappings |
| 176 | 210 | name_mappings = { | ... | ... |
offline_tasks/scripts/load_index_to_redis.py
| ... | ... | @@ -10,11 +10,41 @@ import sys |
| 10 | 10 | from datetime import datetime |
| 11 | 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 | 50 | def load_index_file(file_path, redis_client, key_prefix, expire_seconds=None): | ... | ... |