base.cs 28 KB

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