From ec23f1ddad8f63d75a065a0a391d2e8cbdd0cb6d Mon Sep 17 00:00:00 2001 From: zpc Date: Sat, 7 Dec 2024 17:43:06 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E7=9B=91=E6=8E=A7=E5=AE=9A?= =?UTF-8?q?=E6=97=B6=E5=99=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Api/CloudGaming.ExtApi/appsettings.json | 132 +++++++++--------- .../Monitor/GameMonitorProcessor.cs | 80 +++++++++++ .../Monitor/OrderMonitorProcessor.cs | 2 +- .../Monitor/UserMonitorProcessor.cs | 4 +- 4 files changed, 149 insertions(+), 69 deletions(-) diff --git a/src/CloudGaming/Api/CloudGaming.ExtApi/appsettings.json b/src/CloudGaming/Api/CloudGaming.ExtApi/appsettings.json index 7e6df50..ec2962a 100644 --- a/src/CloudGaming/Api/CloudGaming.ExtApi/appsettings.json +++ b/src/CloudGaming/Api/CloudGaming.ExtApi/appsettings.json @@ -1,72 +1,72 @@ { - "Logging": { - "LogLevel": { - "Default": "Information", - "Microsoft.AspNetCore": "Warning" - } - }, - "AllowedHosts": "*", - "Serilog": { - "Using": [ "Serilog.Sinks.Console", "Serilog.Sinks.File" ], - "MinimumLevel": { - "Default": "Information", - "Override": { - "Microsoft": "Warning", - "System": "Warning" - } + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } }, - "WriteTo": [ - { "Name": "Console" }, - { - "Name": "File", - "Args": { - "path": "../output/extlogs/info/log-.txt", - "rollingInterval": "Day", - "restrictedToMinimumLevel": "Information", //写入日志的级别 - "shared": true - //"outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level}] {Message}{NewLine}{Exception}" + "AllowedHosts": "*", + "Serilog": { + "Using": [ "Serilog.Sinks.Console", "Serilog.Sinks.File" ], + "MinimumLevel": { + "Default": "Information", + "Override": { + "Microsoft": "Warning", + "System": "Warning" + } + }, + "WriteTo": [ + { "Name": "Console" }, + { + "Name": "File", + "Args": { + "path": "output/extlogs/info/log-.txt", + "rollingInterval": "Day", + "restrictedToMinimumLevel": "Information", //写入日志的级别 + "shared": true + //"outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level}] {Message}{NewLine}{Exception}" + } + }, + { + "Name": "File", + "Args": { + "path": "output/extlogs/error/log-.txt", + "rollingInterval": "Day", //日志文件按天滚动生成。 + "restrictedToMinimumLevel": "Error", //写入日志的级别 //包括 Verbose、Debug、Information、Warning、Error 和 Fatal + "shared": true //不占用文件 + // "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level}] {Message}{NewLine}{Exception}" + } + }, + { + "Name": "File", + "Args": { + "path": "output/extlogs/debug/log-.txt", + "rollingInterval": "Day", //日志文件按天滚动生成。 + "restrictedToMinimumLevel": "Debug", //写入日志的级别 //包括 Verbose、Debug、Information、Warning、Error 和 Fatal + "shared": true //不占用文件 + // "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level}] {Message}{NewLine}{Exception}" + } + } + ], + "Enrich": [ "FromLogContext", "WithMachineName", "WithThreadId" ] + }, + "AgileConfig": { + "appId": "CloudGaming", + "secret": "95BB717C61D1ECB0E9FB82C932CC77FF", + "nodes": "http://124.220.55.158:94", //多个节点使用逗号分隔 + "url": "http://124.220.55.158:94", + "env": "TEST", + "name": "extClient", + "UserName": "admin", + "Password": "dbt@com@1234" + }, + //服务器配置 + "Kestrel": { + "Endpoints": { + "Http": { + "Url": "http://*:80" + } } - }, - { - "Name": "File", - "Args": { - "path": "../output/extlogs/error/log-.txt", - "rollingInterval": "Day", //日志文件按天滚动生成。 - "restrictedToMinimumLevel": "Error", //写入日志的级别 //包括 Verbose、Debug、Information、Warning、Error 和 Fatal - "shared": true //不占用文件 - // "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level}] {Message}{NewLine}{Exception}" - } - }, - { - "Name": "File", - "Args": { - "path": "../output/extlogs/debug/log-.txt", - "rollingInterval": "Day", //日志文件按天滚动生成。 - "restrictedToMinimumLevel": "Debug", //写入日志的级别 //包括 Verbose、Debug、Information、Warning、Error 和 Fatal - "shared": true //不占用文件 - // "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level}] {Message}{NewLine}{Exception}" - } - } - ], - "Enrich": [ "FromLogContext", "WithMachineName", "WithThreadId" ] - }, - "AgileConfig": { - "appId": "CloudGaming", - "secret": "95BB717C61D1ECB0E9FB82C932CC77FF", - "nodes": "http://124.220.55.158:94", //多个节点使用逗号分隔 - "url": "http://124.220.55.158:94", - "env": "TEST", - "name": "payClient", - "UserName": "admin", - "Password": "dbt@com@1234" - }, - //服务器配置 - "Kestrel": { - "Endpoints": { - "Http": { - "Url": "http://*:80" - } } - } } diff --git a/src/CloudGaming/Code/CloudGaming.Code/Monitor/GameMonitorProcessor.cs b/src/CloudGaming/Code/CloudGaming.Code/Monitor/GameMonitorProcessor.cs index c82ee56..6a15d80 100644 --- a/src/CloudGaming/Code/CloudGaming.Code/Monitor/GameMonitorProcessor.cs +++ b/src/CloudGaming/Code/CloudGaming.Code/Monitor/GameMonitorProcessor.cs @@ -85,4 +85,84 @@ namespace CloudGaming.Code.Monitor await dao.DaoExt.Context.SaveChangesAsync(); } } + + /// + /// 游戏控制器 + /// + [QuartzTrigger("GameMonitorProcessorHour", "0 10 * * * ?")] + public class GameMonitorProcessorHour : AppJobBase + { + public GameMonitorProcessorHour(IServiceScopeFactory scopeFactory) : base(scopeFactory) + { + } + + public override async Task AppConfigProcessLoop(AppConfig appConfig, AppMonitorInfo appMonitorInfo, IServiceProvider serviceProvider, CloudGamingBase cloudGamingBase) + { + var dao = cloudGamingBase.Dao; + var now = DateTime.Now.AddHours(-1); + int day = int.Parse(now.ToString("yyyyMMdd")); + var newDayHour = now.Date.AddHours(now.Hour); + var oldDayHour = now.Date.AddHours(now.AddHours(1).Hour); + int dayHour = int.Parse(now.ToString("yyyyMMddHH")); + var nowDay = DateOnly.FromDateTime(now); + var gamePlay = dao.DaoPhone.Context.T_Game_PlayGameLog.Where(it => it.CreateDay == day && it.CreateDateTime >= newDayHour && it.CreateDateTime < oldDayHour).AsQueryable(); + //启动游戏次数 + var gamePlayCount = await gamePlay.GroupBy(log => log.Channel).ToDictionaryAsync(it => it.Key ?? "", it => it.Count()); + //启动游戏人数 + var gamePlayLog = await gamePlay.GroupBy(log => log.Channel).Select(group => new + { + Channel = group.Key, + UserCount = group.Select(log => log.UserId).Distinct().Count() + }).ToDictionaryAsync(it => it.Channel ?? "", it => it.UserCount); + // 游玩时间 + var gamePlaySeconds = await gamePlay.GroupBy(log => log.Channel).Select(group => new + { + Channel = group.Key, + PlayGameTotalSeconds = group.Sum(it => it.PlayGameTotalSeconds) + }).ToDictionaryAsync(it => it.Channel ?? "", it => it.PlayGameTotalSeconds); + + // 获取当前统计数据 + var userStatistics = await dao.DaoExt.Context.T_Statistics_GameHour + .Where(it => it.LoginDay == day && it.LoginHour == dayHour) + .ToDictionaryAsync(it => it.Channel ?? ""); + // 更新或创建统计记录 + void UpdateStatistics(string channel, int playGameCount, int playGameTimeCount, int startGameCount) + { + if (!userStatistics.TryGetValue(channel, out var statisticsUser)) + { + statisticsUser = new T_Statistics_GameHour() + { + PlayGameCount = 0, + Channel = channel, + CreatedAt = DateTime.Now, + PlayGameTimeCount = 0, + StartGameCount = 0, + LoginDate = nowDay, + LoginDay = day, + UpdatedAt = DateTime.Now, + LoginHour = dayHour, + }; + dao.DaoExt.Context.T_Statistics_GameHour.Add(statisticsUser); + userStatistics.Add(channel, statisticsUser); + } + statisticsUser.PlayGameCount = playGameCount; + statisticsUser.PlayGameTimeCount = playGameTimeCount > 0 ? playGameTimeCount / 60 / 60 : playGameTimeCount; + statisticsUser.StartGameCount = startGameCount; + statisticsUser.UpdatedAt = DateTime.Now; + } + + var list = dao.DaoExt.Context.T_App_Channel.ToList(); + foreach (var item in list) + { + var key = item.ChannelId; + if (string.IsNullOrEmpty(key)) + { + key = "27001"; + } + UpdateStatistics(key, gamePlayCount.GetValueOrDefault(key, 0), gamePlaySeconds.GetValueOrDefault(key, 0), gamePlayLog.GetValueOrDefault(key, 0)); + + } + await dao.DaoExt.Context.SaveChangesAsync(); + } + } } diff --git a/src/CloudGaming/Code/CloudGaming.Code/Monitor/OrderMonitorProcessor.cs b/src/CloudGaming/Code/CloudGaming.Code/Monitor/OrderMonitorProcessor.cs index 75f73e7..102818f 100644 --- a/src/CloudGaming/Code/CloudGaming.Code/Monitor/OrderMonitorProcessor.cs +++ b/src/CloudGaming/Code/CloudGaming.Code/Monitor/OrderMonitorProcessor.cs @@ -80,7 +80,7 @@ public class OrderMonitorProcessor : AppJobBase } } -[QuartzTrigger("OrderHourMonitorProcessor", "0 5 * * * ?")] +[QuartzTrigger("OrderHourMonitorProcessor", "0 2 * * * ?")] public class OrderHourMonitorProcessor : AppJobBase { public OrderHourMonitorProcessor(IServiceScopeFactory scopeFactory) : base(scopeFactory) diff --git a/src/CloudGaming/Code/CloudGaming.Code/Monitor/UserMonitorProcessor.cs b/src/CloudGaming/Code/CloudGaming.Code/Monitor/UserMonitorProcessor.cs index b23a47c..3b17cbc 100644 --- a/src/CloudGaming/Code/CloudGaming.Code/Monitor/UserMonitorProcessor.cs +++ b/src/CloudGaming/Code/CloudGaming.Code/Monitor/UserMonitorProcessor.cs @@ -91,7 +91,7 @@ public class UserMonitorProcessor : AppJobBase /// /// 用户定时类 /// -[QuartzTrigger("UserHourMonitorProcessor", "0 1 * * * ?")] +[QuartzTrigger("UserHourMonitorProcessor", "0 5 * * * ?")] public class UserHourMonitorProcessor : AppJobBase { public UserHourMonitorProcessor(IServiceScopeFactory scopeFactory) : base(scopeFactory) @@ -122,7 +122,7 @@ public class UserHourMonitorProcessor : AppJobBase // 获取当前统计数据 var userStatistics = await dao.DaoExt.Context.T_Statistics_UserHour - .Where(it => it.LoginDay == day) + .Where(it => it.LoginDay == day && it.LoginHour == dayHour) .ToDictionaryAsync(it => it.Channel ?? ""); // 更新或创建统计记录