base.cs 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577
  1. using dodohold.core;
  2. using CSRedis;
  3. using System.Data;
  4. using System.Diagnostics;
  5. using YunhuiKit;
  6. namespace molilian.core
  7. {
  8. public partial class TkLogCore
  9. {
  10. public static bool save_dailys_log = false;
  11. public static string _test_oaid = "3B191CFA4C6B48F9BA459E915B57743BEC7D424979CC9C51BCAD0C245B1C7BA2";
  12. static TkLogCore()
  13. {
  14. int flag = RedisHelper.Get<int>("turn:save_dailys_log");
  15. if (flag == 1) save_dailys_log = true;
  16. }
  17. private static readonly SemaphoreSlim semaphore = new SemaphoreSlim(10, 10);
  18. public static async Task<int> BatchInsertLogDBAsync(int limit)
  19. {
  20. await semaphore.WaitAsync().ConfigureAwait(false);
  21. try
  22. {
  23. var tasks = EndPointCore.List()
  24. .Where(node => node.is_public_api && !string.IsNullOrEmpty(node.redis_server))
  25. .Where(node => CenterHub.IsCenter ? !node.is_coupon_api : node.is_coupon_api)
  26. .Select(async node =>
  27. {
  28. var redisServer = EndPointCore.GetRedisServer(node);
  29. if (string.IsNullOrEmpty(redisServer)) return 0;
  30. try
  31. {
  32. await using var scope = RedisClientFactory.CreateScope(redisServer);
  33. return BatchInsertLogDB(limit, scope.Client);
  34. }
  35. catch (Exception ex)
  36. {
  37. // TODO: 添加日志记录
  38. return 0;
  39. }
  40. });
  41. var results = await Task.WhenAll(tasks).ConfigureAwait(false);
  42. return results.Sum();
  43. }
  44. catch (Exception)
  45. {
  46. return 0;
  47. }
  48. finally
  49. {
  50. semaphore.Release();
  51. }
  52. }
  53. public static int BatchInsertLogDB(int limit, YunhuiKit.RedisClient redis)
  54. {
  55. int total = 0;
  56. //using var connection = DBContext.GetOpenConnection();
  57. //connection.Open();
  58. //using var transaction = connection.BeginTransaction();
  59. using IDbTransaction transaction = null;
  60. using IDbConnection connection = null;
  61. try
  62. {
  63. Stopwatch stopwatch = new Stopwatch(); // 创建一个计时器
  64. var tasks = new List<Task<int>>
  65. {
  66. RunTaskWithLoggingAsync(() => InsertPromotionImgAsync(limit, redis), "task_insert_promotion_img_logs"),
  67. RunTaskWithLoggingAsync(() => InsertParseTkLogAsync(limit, redis), "task_insert_parse_tb_logs"),
  68. RunTaskWithLoggingAsync(() => InsertParseJDLogAsync(limit, redis), "task_insert_parse_jd_logs"),
  69. RunTaskWithLoggingAsync(() => InsertParsePddLogAsync(limit, redis), "task_insert_parse_pdd_logs"),
  70. RunTaskWithLoggingAsync(() => InsertParseDyLogAsync(limit, redis), "task_insert_parse_dy_logs"),
  71. RunTaskWithLoggingAsync(() => InsertParseKsLogAsync(limit, redis), "task_insert_parse_ks_logs"),
  72. RunTaskWithLoggingAsync(() => InsertToolLogAsync(limit, redis), "task_insert_parse_tool_logs"),
  73. RunTaskWithLoggingAsync(() => InsertDeeplinkLogAsync(limit, redis), "task_insert_parse_deeplink_logs"),
  74. RunTaskWithLoggingAsync(() => InsertCouponLogAsync(limit, redis), "task_insert_parse_coupon_logs"),
  75. RunTaskWithLoggingAsync(() => InsertCpsLogAsync(limit, redis), "task_insert_parse_cps_logs"),
  76. //Task.Run(() => RunTaskWithLogging(() => task_insert_tk_logs(limit, redis), "task_insert_tk_logs")),
  77. //Task.Run(() => RunTaskWithLogging(() => task_insert_parse_tb_logs(limit, redis), "task_insert_parse_tb_logs")),
  78. //Task.Run(() => RunTaskWithLogging(() => task_insert_parse_jd_logs(limit, redis), "task_insert_parse_jd_logs")),
  79. //Task.Run(() => RunTaskWithLogging(() => task_insert_parse_pdd_logs(limit, redis), "task_insert_parse_pdd_logs")),
  80. //Task.Run(() => RunTaskWithLogging(() => task_insert_parse_dy_logs(limit, redis), "task_insert_parse_dy_logs")),
  81. //Task.Run(() => RunTaskWithLogging(() => task_insert_parse_tool_logs(limit, redis), "task_insert_parse_tool_logs")),
  82. //Task.Run(() => RunTaskWithLogging(() => task_insert_parse_deeplink_logs(limit, redis), "task_insert_parse_deeplink_logs")),
  83. //Task.Run(() => RunTaskWithLogging(() => task_insert_parse_coupon_logs(limit, redis), "task_insert_parse_coupon_logs")),
  84. //Task.Run(() => RunTaskWithLogging(() => task_insert_parse_cps_logs(limit, redis), "task_insert_parse_cps_logs")),
  85. //Task.Run(() => RunTaskWithLogging(() => task_insert_promotion_img_logs(limit, redis), "task_insert_promotion_img_logs")),
  86. //Task.Run(() => RunTaskWithLogging(() => task_insert_parse_ks_logs(limit, redis), "task_insert_parse_ks_logs"))
  87. };
  88. // 等待所有任务完成
  89. Task.WhenAll(tasks).Wait();//252行
  90. // 计算所有任务的结果总和
  91. total = tasks.Select(t => t.Result).Sum();
  92. //transaction.Commit();
  93. }
  94. catch (Exception ex)
  95. {
  96. //transaction.Rollback();
  97. // 构建异常详细信息字符串
  98. string detailedError = $"{ex.Message}\n" +
  99. $"堆栈跟踪: {ex.StackTrace}\n";
  100. if (ex.InnerException != null)
  101. {
  102. detailedError += $"内部异常: {ex.InnerException.Message}\n" +
  103. $"内部堆栈跟踪: {ex.InnerException.StackTrace}\n";
  104. }
  105. // 如果异常包含其他数据,也可以记录下来
  106. if (ex.Data != null && ex.Data.Count > 0)
  107. {
  108. detailedError += "附加数据:\n";
  109. foreach (var key in ex.Data.Keys)
  110. {
  111. detailedError += $"{key}: {ex.Data[key]}\n";
  112. }
  113. }
  114. _ = new LoggerLibrary("database_error", "parse_log")
  115. .Info(detailedError)
  116. .SaveAsync();
  117. NotifyCore.Notify(new NifyMessage
  118. {
  119. message = $"【Exception】\n{detailedError}",
  120. priority = NifyMessagePriority.high,
  121. tags = ["red_circle"]
  122. });
  123. }
  124. finally
  125. {
  126. //connection.Close();
  127. }
  128. return total;
  129. }
  130. private static async Task<int> RunTaskWithLoggingAsync(Func<Task<int>> taskFunc, string taskName)
  131. {
  132. LoggerLibrary log = new LoggerLibrary("debug", "BatchInsertLogDB"); // 创建日志对象
  133. Stopwatch stopwatch = new Stopwatch();
  134. stopwatch.Start();
  135. int taskTotal = await taskFunc();
  136. stopwatch.Stop();
  137. log.Info($"{taskName} 耗时: {stopwatch.ElapsedMilliseconds} ms,\t插入记录数: {taskTotal}");
  138. log.SaveAsync();
  139. return taskTotal;
  140. }
  141. /// <summary>
  142. /// 过时方法 随时删除
  143. /// </summary>
  144. /// <param name="channel"></param>
  145. /// <param name="accountId"></param>
  146. /// <param name="accountName"></param>
  147. /// <param name="success"></param>
  148. /// <param name="message"></param>
  149. /// <param name="reason"></param>
  150. private static void saveCache(string channel, int accountId, string accountName, bool success, string message, string reason)
  151. {
  152. saveAccountCache("all", success, message, reason);
  153. saveAccountCache($"{channel}", success, message, reason);
  154. saveAccountCache($"{accountName}", success, message, reason);
  155. if (accountId != 0)
  156. {
  157. //todo 放着跑两天,要将读取的地方改成读取accountid
  158. saveAccountCache($"{channel}_{accountId}", success, message, reason);
  159. }
  160. }
  161. private static void saveAccountCache(string accountName, bool success, string message, string reason)
  162. {
  163. RedisHelper.IncrBy($":total:{accountName}:{DateTime.Now:yyyyMM}");
  164. RedisHelper.IncrBy($":total:{accountName}:{DateTime.Now:yyyyMMdd}");
  165. RedisHelper.IncrBy($":total:{accountName}:{DateTime.Now:yyyyMMddHH}");
  166. string result = success ? "success" : "fail";
  167. RedisHelper.IncrBy($":total:{accountName}:{result}:{DateTime.Now:yyyyMM}");
  168. RedisHelper.IncrBy($":total:{accountName}:{result}:{DateTime.Now:yyyyMMdd}");
  169. RedisHelper.IncrBy($":total:{accountName}:{result}:{DateTime.Now:yyyyMMddHH}");
  170. if (!string.IsNullOrEmpty(message))
  171. {
  172. RedisHelper.SAdd($":total:{accountName}:message:{DateTime.Now:yyyyMM}", message);
  173. RedisHelper.SAdd($":total:{accountName}:message:{DateTime.Now:yyyyMMdd}", message);
  174. RedisHelper.SAdd($":total:{accountName}:message:{DateTime.Now:yyyyMMddHH}", message);
  175. RedisHelper.IncrBy($":total:{accountName}:{message}:{DateTime.Now:yyyyMM}");
  176. RedisHelper.IncrBy($":total:{accountName}:{message}:{DateTime.Now:yyyyMMdd}");
  177. RedisHelper.IncrBy($":total:{accountName}:{message}:{DateTime.Now:yyyyMMddHH}");
  178. RedisHelper.IncrBy($":total:{accountName}:message:{message}:{DateTime.Now:yyyyMM}");
  179. RedisHelper.IncrBy($":total:{accountName}:message:{message}:{DateTime.Now:yyyyMMdd}");
  180. RedisHelper.IncrBy($":total:{accountName}:message:{message}:{DateTime.Now:yyyyMMddHH}");
  181. }
  182. if (!string.IsNullOrEmpty(reason))
  183. {
  184. RedisHelper.SAdd($":total:{accountName}:reason:{DateTime.Now:yyyyMM}", reason);
  185. RedisHelper.SAdd($":total:{accountName}:reason:{DateTime.Now:yyyyMMdd}", reason);
  186. RedisHelper.SAdd($":total:{accountName}:reason:{DateTime.Now:yyyyMMddHH}", reason);
  187. RedisHelper.IncrBy($":total:{accountName}:{reason}:{DateTime.Now:yyyyMM}");
  188. RedisHelper.IncrBy($":total:{accountName}:{reason}:{DateTime.Now:yyyyMMdd}");
  189. RedisHelper.IncrBy($":total:{accountName}:{reason}:{DateTime.Now:yyyyMMddHH}");
  190. RedisHelper.IncrBy($":total:{accountName}:reason:{reason}:{DateTime.Now:yyyyMM}");
  191. RedisHelper.IncrBy($":total:{accountName}:reason:{reason}:{DateTime.Now:yyyyMMdd}");
  192. RedisHelper.IncrBy($":total:{accountName}:reason:{reason}:{DateTime.Now:yyyyMMddHH}");
  193. }
  194. }
  195. private static async Task saveUnionCouponParseCacheAsync(TkDataDTO data)
  196. {
  197. string cacheKey = $":cache:parse:{data.ip}_{data.oaid}_{data.itemId}";
  198. await EndPointCore.ProcessEndPointNodesAsync(node =>
  199. {
  200. if (!node.is_coupon_api) return Task.CompletedTask;
  201. if (string.IsNullOrEmpty(node.redis_server)) return Task.CompletedTask;
  202. var redis = RedisClientManager.GetRedisClient(node.redis_server);
  203. redis.Set(cacheKey, 1, 2 * 86400);
  204. return Task.CompletedTask;
  205. });
  206. }
  207. private async static Task saveClientRequestTotalAsync(TkChannelEnum channel, string ip, string oaid)
  208. {
  209. await saveClientRequestTotalAsync(channel.ToString(), ip, oaid);
  210. }
  211. private static async Task saveClientRequestTotalAsync(string channel, string ip, string oaid)
  212. {
  213. await EndPointCore.ProcessEndPointNodesAsync(node =>
  214. {
  215. if (string.IsNullOrEmpty(node.redis_server)) return Task.CompletedTask;
  216. if (!node.is_public_api) return Task.CompletedTask;
  217. #if DEBUG
  218. switch (node.name)
  219. {
  220. case "bj":
  221. node.redis_server = "101.200.46.46:6379,password=pKBiS4ka2IpXayIdcx00,defaultDatabase=0,idleTimeout=20000,preheat=3,tryit=2,ssl=false,prefix=webhook";
  222. break;
  223. case "gz":
  224. node.redis_server = "8.138.110.158:6379,password=pKBiS4ka2IpXayIdcx00,defaultDatabase=0,idleTimeout=20000,preheat=3,tryit=2,ssl=false,prefix=webhook";
  225. break;
  226. case "coupon1":
  227. node.redis_server = "123.56.185.166:6379,password=pKBiS4ka2IpXayIdcx00,defaultDatabase=0,idleTimeout=20000,preheat=3,tryit=2,ssl=false,prefix=coupon";
  228. break;
  229. default: return Task.CompletedTask;
  230. }
  231. #endif
  232. var redis = RedisClientManager.GetRedisClient(node.redis_server);
  233. string cacheKey = $":cache:{channel}:ip:{DateTime.Now:yyyyMMdd}:{ip}";
  234. redis.IncrBy(cacheKey);
  235. redis.Expire(cacheKey, 86400);
  236. if (!string.IsNullOrEmpty(oaid))
  237. {
  238. cacheKey = $":cache:{channel}:oaid:{DateTime.Now:yyyyMMdd}:{oaid}";
  239. redis.IncrBy(cacheKey);
  240. redis.Expire(cacheKey, 86400);
  241. }
  242. return Task.CompletedTask;
  243. });
  244. }
  245. public static bool InBlacklist(string blacklist, string oaid)
  246. {
  247. if (string.IsNullOrEmpty(blacklist)) return false;
  248. var arr = blacklist.Split(new[] { "\r\n" }, StringSplitOptions.None)
  249. .Select(s => s.Trim()).ToArray();
  250. return arr.Contains(oaid);
  251. }
  252. public static int getClientRequestTotalByOAID(TkChannelEnum channel, string oaid)
  253. {
  254. if (string.IsNullOrEmpty(oaid)) return 0;
  255. string cacheKey = $":cache:{channel}:oaid:{DateTime.Now:yyyyMMdd}:{oaid}";
  256. return RedisHelper.Get<int>(cacheKey);
  257. }
  258. public static int getClientRequestTotalByIp(TkChannelEnum channel, string ip)
  259. {
  260. if (string.IsNullOrEmpty(ip)) return 0;
  261. string cacheKey = $":cache:{channel}:ip:{DateTime.Now:yyyyMMdd}:{ip}";
  262. return RedisHelper.Get<int>(cacheKey);
  263. }
  264. public static int getClientRequestTotalByOAID(string channel, string oaid)
  265. {
  266. if (string.IsNullOrEmpty(oaid)) return 0;
  267. string cacheKey = $":cache:{channel}:oaid:{DateTime.Now:yyyyMMdd}:{oaid}";
  268. return RedisHelper.Get<int>(cacheKey);
  269. }
  270. public static int getClientRequestTotalByIp(string channel, string ip)
  271. {
  272. if (string.IsNullOrEmpty(ip)) return 0;
  273. string cacheKey = $":cache:{channel}:ip:{DateTime.Now:yyyyMMdd}:{ip}";
  274. return RedisHelper.Get<int>(cacheKey);
  275. }
  276. private static void saveClientRequestTotal(CpsChannelEnum channel, string ip, string oaid)
  277. {
  278. string cacheKey = $":cache:cps_{channel}:ip:{DateTime.Now:yyyyMMdd}:{ip}";
  279. RedisHelper.IncrBy(cacheKey);
  280. RedisHelper.Expire(cacheKey, 86400);
  281. if (!string.IsNullOrEmpty(oaid))
  282. {
  283. cacheKey = $":cache:cps_{channel}:oaid:{DateTime.Now:yyyyMMdd}:{oaid}";
  284. RedisHelper.IncrBy(cacheKey);
  285. RedisHelper.Expire(cacheKey, 86400);
  286. }
  287. }
  288. public static int getClientRequestTotalByOAID(CpsChannelEnum channel, string oaid)
  289. {
  290. if (string.IsNullOrEmpty(oaid)) return 0;
  291. string cacheKey = $":cache:cps_{channel}:oaid:{DateTime.Now:yyyyMMdd}:{oaid}";
  292. return RedisHelper.Get<int>(cacheKey);
  293. }
  294. public static int getClientRequestTotalByIp(CpsChannelEnum channel, string ip)
  295. {
  296. if (string.IsNullOrEmpty(ip)) return 0;
  297. string cacheKey = $":cache:cps_{channel}:ip:{DateTime.Now:yyyyMMdd}:{ip}";
  298. return RedisHelper.Get<int>(cacheKey);
  299. }
  300. private static async Task SaveParseCacheAsync(string channel, int accountId, string accountName,
  301. bool success, string message, string reason, string deeplink)
  302. {
  303. string dp_flag = deeplink switch
  304. {
  305. "" => "none",
  306. "tbopen://m.taobao.com/tbopen/index.html" or
  307. "pinduoduo://com.xunmeng.pinduoduo/" or
  308. "snssdk1128://feed?refer=web" or
  309. "bdnetdisk://n/action.EXTERNAL_ACTIVITY" or
  310. "openapp.jdmobile://virtual?params=" or "openapp.jdmobile://" => "home",
  311. _ => success ? "success" : "fail",
  312. };
  313. //关于dp的缓存
  314. await SaveParseAccountCacheAsync($"dp_{dp_flag}:all", success, message, reason);
  315. await SaveParseAccountCacheAsync($"dp_{dp_flag}:{channel}", success, message, reason);
  316. await SaveParseAccountCacheAsync($"dp_{dp_flag}:{accountName}", success, message, reason);
  317. if (accountId != 0)
  318. {
  319. await SaveParseAccountCacheAsync($"dp_{dp_flag}:{channel}_{accountId}", success, message, reason);
  320. }
  321. await SaveParseAccountCacheAsync("all", success, message, reason);
  322. await SaveParseAccountCacheAsync($"{channel}", success, message, reason);
  323. await SaveParseAccountCacheAsync($"{accountName}", success, message, reason);
  324. if (accountId != 0)
  325. {
  326. //todo 放着跑两天,要将读取的地方改成读取accountid
  327. await SaveParseAccountCacheAsync($"{channel}_{accountId}", success, message, reason);
  328. }
  329. }
  330. private static async Task SaveParseAccountCacheAsync(string accountName, bool success,
  331. string message, string reason)
  332. {
  333. await RedisKit.IncrByAsync($":parse_total:{accountName}:{DateTime.Now:yyyyMM}");
  334. await RedisKit.IncrByAsync($":parse_total:{accountName}:{DateTime.Now:yyyyMMdd}");
  335. await RedisKit.IncrByAsync($":parse_total:{accountName}:{DateTime.Now:yyyyMMddHH}");
  336. string result = success ? "success" : "fail";
  337. await RedisKit.IncrByAsync($":parse_total:{accountName}:{result}:{DateTime.Now:yyyyMM}");
  338. await RedisKit.IncrByAsync($":parse_total:{accountName}:{result}:{DateTime.Now:yyyyMMdd}");
  339. await RedisKit.IncrByAsync($":parse_total:{accountName}:{result}:{DateTime.Now:yyyyMMddHH}");
  340. if (!string.IsNullOrEmpty(message))
  341. {
  342. await RedisKit.SAddAsync($":parse_total:{accountName}:message:{DateTime.Now:yyyyMM}", message);
  343. await RedisKit.SAddAsync($":parse_total:{accountName}:message:{DateTime.Now:yyyyMMdd}", message);
  344. await RedisKit.SAddAsync($":parse_total:{accountName}:message:{DateTime.Now:yyyyMMddHH}", message);
  345. await RedisKit.IncrByAsync($":parse_total:{accountName}:{message}:{DateTime.Now:yyyyMM}");
  346. await RedisKit.IncrByAsync($":parse_total:{accountName}:{message}:{DateTime.Now:yyyyMMdd}");
  347. await RedisKit.IncrByAsync($":parse_total:{accountName}:{message}:{DateTime.Now:yyyyMMddHH}");
  348. await RedisKit.IncrByAsync($":parse_total:{accountName}:message:{message}:{DateTime.Now:yyyyMM}");
  349. await RedisKit.IncrByAsync($":parse_total:{accountName}:message:{message}:{DateTime.Now:yyyyMMdd}");
  350. await RedisKit.IncrByAsync($":parse_total:{accountName}:message:{message}:{DateTime.Now:yyyyMMddHH}");
  351. }
  352. if (!string.IsNullOrEmpty(reason))
  353. {
  354. await RedisKit.SAddAsync($":parse_total:{accountName}:reason:{DateTime.Now:yyyyMM}", reason);
  355. await RedisKit.SAddAsync($":parse_total:{accountName}:reason:{DateTime.Now:yyyyMMdd}", reason);
  356. await RedisKit.SAddAsync($":parse_total:{accountName}:reason:{DateTime.Now:yyyyMMddHH}", reason);
  357. await RedisKit.IncrByAsync($":parse_total:{accountName}:{reason}:{DateTime.Now:yyyyMM}");
  358. await RedisKit.IncrByAsync($":parse_total:{accountName}:{reason}:{DateTime.Now:yyyyMMdd}");
  359. await RedisKit.IncrByAsync($":parse_total:{accountName}:{reason}:{DateTime.Now:yyyyMMddHH}");
  360. await RedisKit.IncrByAsync($":parse_total:{accountName}:reason:{reason}:{DateTime.Now:yyyyMM}");
  361. await RedisKit.IncrByAsync($":parse_total:{accountName}:reason:{reason}:{DateTime.Now:yyyyMMdd}");
  362. await RedisKit.IncrByAsync($":parse_total:{accountName}:reason:{reason}:{DateTime.Now:yyyyMMddHH}");
  363. }
  364. }
  365. private static void saveParseCache(string channel, int accountId, string accountName,
  366. bool success, string message, string reason, string deeplink)
  367. {
  368. string dp_flag = deeplink switch
  369. {
  370. "" => "none",
  371. "tbopen://m.taobao.com/tbopen/index.html" or
  372. "pinduoduo://com.xunmeng.pinduoduo/" or
  373. "snssdk1128://feed?refer=web" or
  374. "bdnetdisk://n/action.EXTERNAL_ACTIVITY" or
  375. "openapp.jdmobile://virtual?params=" or "openapp.jdmobile://" => "home",
  376. _ => success ? "success" : "fail",
  377. };
  378. //关于dp的缓存
  379. saveParseAccountCache($"dp_{dp_flag}:all", success, message, reason);
  380. saveParseAccountCache($"dp_{dp_flag}:{channel}", success, message, reason);
  381. saveParseAccountCache($"dp_{dp_flag}:{accountName}", success, message, reason);
  382. if (accountId != 0)
  383. {
  384. saveParseAccountCache($"dp_{dp_flag}:{channel}_{accountId}", success, message, reason);
  385. }
  386. saveParseAccountCache("all", success, message, reason);
  387. saveParseAccountCache($"{channel}", success, message, reason);
  388. saveParseAccountCache($"{accountName}", success, message, reason);
  389. if (accountId != 0)
  390. {
  391. //todo 放着跑两天,要将读取的地方改成读取accountid
  392. saveParseAccountCache($"{channel}_{accountId}", success, message, reason);
  393. }
  394. }
  395. private static void saveParseAccountCache(string accountName, bool success,
  396. string message, string reason)
  397. {
  398. RedisHelper.IncrBy($":parse_total:{accountName}:{DateTime.Now:yyyyMM}");
  399. RedisHelper.IncrBy($":parse_total:{accountName}:{DateTime.Now:yyyyMMdd}");
  400. RedisHelper.IncrBy($":parse_total:{accountName}:{DateTime.Now:yyyyMMddHH}");
  401. string result = success ? "success" : "fail";
  402. RedisHelper.IncrBy($":parse_total:{accountName}:{result}:{DateTime.Now:yyyyMM}");
  403. RedisHelper.IncrBy($":parse_total:{accountName}:{result}:{DateTime.Now:yyyyMMdd}");
  404. RedisHelper.IncrBy($":parse_total:{accountName}:{result}:{DateTime.Now:yyyyMMddHH}");
  405. if (!string.IsNullOrEmpty(message))
  406. {
  407. RedisHelper.SAdd($":parse_total:{accountName}:message:{DateTime.Now:yyyyMM}", message);
  408. RedisHelper.SAdd($":parse_total:{accountName}:message:{DateTime.Now:yyyyMMdd}", message);
  409. RedisHelper.SAdd($":parse_total:{accountName}:message:{DateTime.Now:yyyyMMddHH}", message);
  410. RedisHelper.IncrBy($":parse_total:{accountName}:{message}:{DateTime.Now:yyyyMM}");
  411. RedisHelper.IncrBy($":parse_total:{accountName}:{message}:{DateTime.Now:yyyyMMdd}");
  412. RedisHelper.IncrBy($":parse_total:{accountName}:{message}:{DateTime.Now:yyyyMMddHH}");
  413. RedisHelper.IncrBy($":parse_total:{accountName}:message:{message}:{DateTime.Now:yyyyMM}");
  414. RedisHelper.IncrBy($":parse_total:{accountName}:message:{message}:{DateTime.Now:yyyyMMdd}");
  415. RedisHelper.IncrBy($":parse_total:{accountName}:message:{message}:{DateTime.Now:yyyyMMddHH}");
  416. }
  417. if (!string.IsNullOrEmpty(reason))
  418. {
  419. RedisHelper.SAdd($":parse_total:{accountName}:reason:{DateTime.Now:yyyyMM}", reason);
  420. RedisHelper.SAdd($":parse_total:{accountName}:reason:{DateTime.Now:yyyyMMdd}", reason);
  421. RedisHelper.SAdd($":parse_total:{accountName}:reason:{DateTime.Now:yyyyMMddHH}", reason);
  422. RedisHelper.IncrBy($":parse_total:{accountName}:{reason}:{DateTime.Now:yyyyMM}");
  423. RedisHelper.IncrBy($":parse_total:{accountName}:{reason}:{DateTime.Now:yyyyMMdd}");
  424. RedisHelper.IncrBy($":parse_total:{accountName}:{reason}:{DateTime.Now:yyyyMMddHH}");
  425. RedisHelper.IncrBy($":parse_total:{accountName}:reason:{reason}:{DateTime.Now:yyyyMM}");
  426. RedisHelper.IncrBy($":parse_total:{accountName}:reason:{reason}:{DateTime.Now:yyyyMMdd}");
  427. RedisHelper.IncrBy($":parse_total:{accountName}:reason:{reason}:{DateTime.Now:yyyyMMddHH}");
  428. }
  429. }
  430. public static async Task<int> GetTotalAsync(string keyname, bool all_node = true)
  431. {
  432. try
  433. {
  434. var tasks = EndPointCore.List()
  435. .Where(node => node.is_public_api && !string.IsNullOrEmpty(node.redis_server))
  436. .Where(node => all_node || (CenterHub.IsCenter ? !node.is_coupon_api : node.is_coupon_api))
  437. .Select(async node =>
  438. {
  439. var redisServer = EndPointCore.GetRedisServer(node);
  440. if (string.IsNullOrEmpty(redisServer))
  441. return 0;
  442. try
  443. {
  444. await using var scope = RedisClientFactory.CreateScope(redisServer);
  445. return await scope.Client.GetAsync<int>(keyname);
  446. }
  447. catch (Exception)
  448. {
  449. return 0;
  450. }
  451. });
  452. var results = await Task.WhenAll(tasks);
  453. return results.Sum();
  454. }
  455. catch (Exception)
  456. {
  457. return 0;
  458. }
  459. }
  460. public static async Task<string[]> GetTotalKeysAsync(string keyname, bool all_node = true)
  461. {
  462. var tasks = EndPointCore.List()
  463. .Where(node => node.is_public_api && !string.IsNullOrEmpty(node.redis_server))
  464. .Where(node => all_node || (CenterHub.IsCenter ? !node.is_coupon_api : node.is_coupon_api))
  465. .Select(async node =>
  466. {
  467. try
  468. {
  469. var redisServer = EndPointCore.GetRedisServer(node);
  470. if (string.IsNullOrEmpty(redisServer)) return [];
  471. using var scope = RedisClientFactory.CreateScope(redisServer);
  472. return await scope.Client.SMembersAsync<string>(keyname);
  473. }
  474. catch (Exception ex)
  475. {
  476. return [];
  477. }
  478. });
  479. var results = await Task.WhenAll(tasks);
  480. return results.SelectMany(x => x).Distinct().ToArray();
  481. }
  482. }
  483. }