Files
mapo-iob-man/IOB-MAN.Core/Services/FluxLogManService.cs
T
2025-07-24 18:59:00 +02:00

351 lines
12 KiB
C#

using EgwCoreLib.Utils;
using IOB_MAN.Core.Config;
using IOB_MAN.Core.Data;
using IOB_MAN.Core.DTO;
using IOB_MAN.Core.Models;
using Newtonsoft.Json;
using NLog;
using StackExchange.Redis;
using System.Collections.Concurrent;
using System.Diagnostics;
using System.Reflection;
using System.Runtime;
using static IOB_MAN.Core.CoreEnum;
namespace IOB_MAN.Core.Services
{
public class FluxLogManService
{
#region Public Constructors
/// <summary>
/// Init classe
/// </summary>
public FluxLogManService()
{
try
{
string startDir = Path.GetDirectoryName(AppContext.BaseDirectory)!;
Log.Trace($"LoadConf starting | startDir: {startDir} | target Framework: {AppContext.TargetFrameworkName}");
ConfDirBase = startDir;
// init configurazioni
DoReloadConfig();
// init REDIS obj
DoSetupRedis();
Log.Trace($"Init complete | Redis conn OK | ConfPathApp: {ConfPathApp} | ConfPathIob: {ConfPathIob}");
}
catch (Exception exc)
{
Log.Error($"Error in AppControlService.init:{Environment.NewLine}{exc}");
}
}
#endregion Public Constructors
#region Public Events
/// <summary>
/// Evento richiesta apertura dettaglio fluxlog
/// </summary>
public event Action<string> EA_FluxLogReq = null!;
#endregion Public Events
#region Public Properties
/// <summary>
/// Abilitazione autorestart
/// </summary>
public bool AutoRestartEnabled { get; set; } = true;
public int CheckRestartPeriod
{
get => currAppConf.TaskData.TimerCheckMSec;
set => currAppConf.TaskData.TimerCheckMSec = value;
}
public string ConfDirIob
{
get => confDirIob;
set => confDirIob = value;
}
/// <summary>
/// Configurazione IOB in sola lettura
/// </summary>
public IobManConfig CurrIobConf
{
get => currIobConf;
}
/// <summary>
/// Abilitazione locale notifiche da conf
/// </summary>
public bool EnableNotify
{
get => currAppConf.EnableNotify;
}
public List<IobAdapt> ListIobAdapters { get; set; } = new List<IobAdapt>();
#endregion Public Properties
#region Public Methods
/// <summary>
/// Legge il file di configurazione APP e poi quello degli IobAdaptConf
/// </summary>
public void DoReloadConfig()
{
ConfPathApp = Path.Combine(ConfDirBase, AppConfName);
if (File.Exists(ConfPathApp))
{
string rawData = File.ReadAllText(ConfPathApp);
if (!string.IsNullOrEmpty(rawData))
{
try
{
currAppConf = JsonConvert.DeserializeObject<AppSettings>(rawData) ?? new AppSettings();
}
catch { }
}
}
// sistemo conf IobAdaptConf da gestire
if (currAppConf.IobAdapt != null && !string.IsNullOrEmpty(currAppConf.IobAdapt.ConfFile))
{
ConfDirIob = Path.Combine(ConfDirBase, currAppConf.IobAdapt.ConfDir);
ConfPathIob = Path.Combine(ConfDirIob, currAppConf.IobAdapt.ConfFile);
if (File.Exists(ConfPathIob))
{
string rawData = File.ReadAllText(ConfPathIob);
if (!string.IsNullOrEmpty(rawData))
{
try
{
currIobConf = JsonConvert.DeserializeObject<IobManConfig>(rawData) ?? new IobManConfig();
TargetIobList = currIobConf.ListTarget;
}
catch { }
}
}
}
}
/// <summary>
/// Recupera da REDIS pareto frequenza di TUTTI i FluxLog giornalieri per IOB
/// </summary>
/// <param name="codIob"></param>
/// <param name="dtReq"></param>
/// <returns></returns>
public List<FluxLogStatsDTO.ParetoVals> FluxLogDailyPareto(string codIob, DateTime dtReq)
{
// ora imposto la stringa
List<FluxLogStatsDTO.ParetoVals> answ = new List<FluxLogStatsDTO.ParetoVals>();
string redIobTrackKey = RedisIobCache.redHash(IobType(codIob), $"IOB:FluxLog:{codIob}");
string rKey = $"{redIobTrackKey}:DayStats:{dtReq:yyMMdd}";
var dictFL = redGetHashDict(rKey);
// se trovo riordino...
if (dictFL != null && dictFL.Count > 0)
{
answ = dictFL
.Select(x => new FluxLogStatsDTO.ParetoVals(x.Key, x.Value))
.OrderByDescending(x => x.Freq)
.ToList();
}
return answ;
}
/// <summary>
/// Elenco dettaglio record giornaliero
/// </summary>
/// <param name="codIob"></param>
/// <param name="dtReq"></param>
/// <param name="codFlux"></param>
/// <returns></returns>
public List<FluxLogStatsDTO.DataLog> FluxLogDataLog(string codIob, DateTime dtReq, string codFlux)
{ // ora imposto la stringa
List<FluxLogStatsDTO.DataLog> answ = new List<FluxLogStatsDTO.DataLog>();
string redIobTrackKey = RedisIobCache.redHash(IobType(codIob), $"IOB:FluxLog:{codIob}");
string rKey = $"{redIobTrackKey}:DataLog:{dtReq:yyMMdd}:{codFlux}";
var dictFL = redGetHashDict(rKey);
// se trovo riordino...
if (dictFL != null && dictFL.Count > 0)
{
answ = dictFL
.Select(x => new FluxLogStatsDTO.DataLog(x.Key, x.Value))
.OrderByDescending(x => x.DataOra)
.ToList();
}
return answ;
}
/// <summary>
/// Recupera da REDIS pareto frequenza valori di un FluxLog giornalieri per IOB
/// </summary>
/// <param name="codIob"></param>
/// <param name="dtReq"></param>
/// <param name="codFlux"></param>
/// <returns></returns>
public List<FluxLogStatsDTO.ParetoVals> FluxLogDetailPareto(string codIob, DateTime dtReq, string codFlux)
{
// ora imposto la stringa
List<FluxLogStatsDTO.ParetoVals> answ = new List<FluxLogStatsDTO.ParetoVals>();
string redIobTrackKey = RedisIobCache.redHash(IobType(codIob), $"IOB:FluxLog:{codIob}");
string rKey = $"{redIobTrackKey}:DetailStats:{dtReq:yyMMdd}:{codFlux}";
var dictFL = redGetHashDict(rKey);
// se trovo riordino...
if (dictFL != null && dictFL.Count > 0)
{
answ = dictFL
.Select(x => new FluxLogStatsDTO.ParetoVals(x.Key, x.Value))
.OrderByDescending(x => x.Freq)
.ToList();
}
return answ;
}
/// <summary>
/// Restituisce conf del target IOB dato nome
/// </summary>
/// <param name="codTarget"></param>
/// <returns></returns>
public TargetConfig GetTargetConf(string codTarget)
{
TargetConfig answ = new TargetConfig();
if (currIobConf.ListTarget.ContainsKey(codTarget))
{
answ = currIobConf.ListTarget[codTarget];
}
return answ;
}
public string IobType(string codIOB)
{
string answ = "";
if (!string.IsNullOrEmpty(codIOB))
{
if (currIobConf.ListIOB.ContainsKey(codIOB))
{
answ = currIobConf.ListIOB[codIOB];
}
}
return answ;
}
public void RequestLoadFLogData(string CodIOB)
{
if (EA_FluxLogReq != null)
{
EA_FluxLogReq?.Invoke(CodIOB);
}
}
#endregion Public Methods
#region Protected Fields
protected string ConfDirBase = "";
protected string DeviceName = "";
#endregion Protected Fields
#region Protected Properties
protected AppSettings currAppConf { get; set; } = new AppSettings();
protected IobManConfig currIobConf { get; set; } = new IobManConfig();
#endregion Protected Properties
#region Private Fields
private static JsonSerializerSettings? JSSettings;
/// <summary>
/// Classe logger
/// </summary>
private static Logger Log = LogManager.GetCurrentClassLogger();
private string AppConfName = "appsettings.json";
private string confDirIob = "";
/// <summary>
/// Path file di conf Applicazione
/// </summary>
private string ConfPathApp = "";
/// <summary>
/// Path file di conf IobAdaptConf
/// </summary>
private string ConfPathIob = "";
/// <summary>
/// Oggetto currentDb Redis
/// </summary>
private IDatabase RedisDb = null!;
/// <summary>
/// Dizionario applicazioni target gestite
/// </summary>
private Dictionary<string, TargetConfig> TargetIobList = new Dictionary<string, TargetConfig>();
#endregion Private Fields
#region Private Properties
/// <summary>
/// Oggetto per connessione a REDIS
/// </summary>
private ConnectionMultiplexer RedisConnMPlex { get; set; } = null!;
#endregion Private Properties
#region Private Methods
private void DoSetupRedis()
{
string redisConnStr = currAppConf.Redis;
RedisConnMPlex = ConnectionMultiplexer.Connect(redisConnStr);
RedisDb = this.RedisConnMPlex.GetDatabase();
// json serializer... FIX errore loop circolare https://www.ryadel.com/en/jsonserializationexception-self-referencing-loop-detected-error-fix-entity-framework-asp-net-core/
JSSettings = new JsonSerializerSettings()
{
ReferenceLoopHandling = ReferenceLoopHandling.Ignore
};
}
/// <summary>
/// Recupera tutti i valori dalla hash in formato Dictionary
/// </summary>
/// <param name="hashKey"></param>
/// <returns></returns>
private Dictionary<string, string> redGetHashDict(string hashKey)
{
Dictionary<string, string> answ = new Dictionary<string, string>();
// cerco se ci sia valore in redis...
try
{
RedisKey chiave = hashKey;
HashEntry[] valori = RedisDb.HashGetAll(chiave);
foreach (HashEntry item in valori)
{
if (item.Name.HasValue && item.Value.HasValue)
{
answ.Add($"{item.Name}", $"{item.Value}");
}
}
}
catch (Exception exc)
{
Log.Error($"redGetHashDict:{Environment.NewLine}{exc}");
}
return answ;
}
#endregion Private Methods
}
}