update con log aggregato chiamate frequenti

This commit is contained in:
Samuele Locatelli
2025-03-29 09:27:45 +01:00
parent 26c6900c79
commit 7390a01a12
7 changed files with 250 additions and 56 deletions
+51 -43
View File
@@ -26,6 +26,56 @@
</div>
</div>
@if (showConfirmResult)
{
<div class="border border-info border-2 rounded-3 my-2 p-2">
<div class="row">
<div class="col-6">
<b>Conferma Produzione</b> effettuata alle @($"{lastConfProd:HH:mm:ss}")
</div>
<div class="col-6">
<div class="d-flex justify-content-between lh-sm text-success">
@if (lastPzBuoni > 0)
{
<span>Pz Buoni</span>
<span class="fw-bold">@lastPzBuoni</span>
}
else
{
<span class="text-secondary">Pz Buoni</span>
<span class="text-secondary">@lastPzBuoni</span>
}
</div>
<div class="d-flex justify-content-between lh-sm text-danger">
@if (lastPzScarto > 0)
{
<span>Pz scarto</span>
<span>@lastPzScarto</span>
}
else
{
<span class="text-secondary">Pz scarto</span>
<span class="text-secondary">@lastPzScarto</span>
}
</div>
<div class="d-flex justify-content-between lh-sm text-info">
@if (lastPzRilav > 0)
{
<span>Cicli Rilav.</span>
<span>@lastPzRilav</span>
}
else
{
<span class="text-secondary">Cicli Rilav.</span>
<span class="text-secondary">@lastPzRilav</span>
}
</div>
</div>
</div>
</div>
}
@if (confProdActive)
{
<div class="cardBg bg-dark bg-gradient p-2 mt-2 border border-success border-2">
@@ -117,6 +167,7 @@
</div>
</div>
}
<div class="col-12">
<div class="row textCondens mt-2 px-2">
<div class="col-12 py-0 text-start text-uppercase lh-1 fw-bold">
@@ -210,49 +261,6 @@
</div>
</div>
@if (showConfirmResult)
{
<div class="border border-info border-2 rounded-3 my-2 p-2">
<b>Conferma Produzione</b> effettuata alle @($"{lastConfProd:HH:mm:ss}")
<div class="d-flex justify-content-between lh-sm text-success">
@if (lastPzBuoni > 0)
{
<span>Pz Buoni</span>
<span class="fw-bold">@lastPzBuoni</span>
}
else
{
<span class="text-secondary">Pz Buoni</span>
<span class="text-secondary">@lastPzBuoni</span>
}
</div>
<div class="d-flex justify-content-between lh-sm text-danger">
@if (lastPzScarto > 0)
{
<span>Pz scarto</span>
<span>@lastPzScarto</span>
}
else
{
<span class="text-secondary">Pz scarto</span>
<span class="text-secondary">@lastPzScarto</span>
}
</div>
<div class="d-flex justify-content-between lh-sm text-info">
@if (lastPzRilav > 0)
{
<span>Cicli Rilav.</span>
<span>@lastPzRilav</span>
}
else
{
<span class="text-secondary">Cicli Rilav.</span>
<span class="text-secondary">@lastPzRilav</span>
}
</div>
</div>
}
@if (!confProdActive)
{
<div class="col-12">
+1 -1
View File
@@ -3,7 +3,7 @@
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<Nullable>enable</Nullable>
<Version>6.16.2503.2719</Version>
<Version>6.16.2503.2909</Version>
<ImplicitUsings>enable</ImplicitUsings>
<RootNamespace>MP_TAB3</RootNamespace>
</PropertyGroup>
+1 -1
View File
@@ -1,6 +1,6 @@
<body>
<i>Modulo MAPOSPEC </i>
<h4>Versione: 6.16.2503.2719</h4>
<h4>Versione: 6.16.2503.2909</h4>
<br /> Note di rilascio:
<ul>
<li>
+1 -1
View File
@@ -1 +1 @@
6.16.2503.2719
6.16.2503.2909
+1 -1
View File
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<item>
<version>6.16.2503.2719</version>
<version>6.16.2503.2909</version>
<url>https://nexus.steamware.net/repository/SWS/MP-TAB3/stable/LAST/MP-TAB3.zip</url>
<changelog>https://nexus.steamware.net/repository/SWS/MP-TAB3/stable/LAST/ChangeLog.html</changelog>
<mandatory>false</mandatory>
+119
View File
@@ -0,0 +1,119 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace MP.Data.Services
{
/// <summary>
/// Gestore statistiche esecuzione processi x analisi timing
/// </summary>
public class ExecStatsCollector
{
#region Public Methods
/// <summary>
/// restituisce una stringa da poter emettere in log con il summary degli eventi tracciati ed eventuale reset...
/// </summary>
/// <param name="CallName"></param>
/// <param name="resetCount"></param>
/// <returns></returns>
public string GetCallSum(string CallName, bool resetCount)
{
string answ = "";
if (TrackData.ContainsKey(CallName))
{
var reqRec = TrackData[CallName];
answ = $"{CallName} | {reqRec.NumCall} x {reqRec.AvgTime:N3}ms | min: {reqRec.MinTime:N3} | MAX: {reqRec.MaxTime:N3}";
// se richiede reset --> effettuo
if (resetCount)
{
TrackData[CallName].ListMsRec = new List<double>();
}
}
return answ;
}
/// <summary>
/// Accumula record di tracciamento info esecuzione e restituisce numero elementi finali
/// </summary>
/// <param name="CallName">nome chiamata da registrare</param>
/// <param name="msDuration">Durata in ms</param>
/// <returns></returns>
public int RecordCall(string CallName, double msDuration)
{
if (TrackData.ContainsKey(CallName))
{
TrackData[CallName].ListMsRec.Add(msDuration);
}
else
{
TrackData.Add(CallName, new RecordData() { ListMsRec = new List<double>() { msDuration } });
}
return TrackData[CallName].NumCall;
}
#endregion Public Methods
#region Public Classes
/// <summary>
/// Record atomico informazioni x un dato task tracciato
/// </summary>
public class RecordData
{
#region Public Properties
/// <summary>
/// Tempo medio
/// </summary>
public double AvgTime
{
get => ListMsRec.Sum(x => x) / (NumCall > 0 ? NumCall : 1);
}
/// <summary>
/// Lista registrazioni di tempi esecuzione in ms
/// </summary>
public List<double> ListMsRec { get; set; } = new List<double>();
/// <summary>
/// Tempo Massimo
/// </summary>
public double MaxTime
{
get => ListMsRec.OrderByDescending(x => x).FirstOrDefault();
}
/// <summary>
/// Tempo minimo
/// </summary>
public double MinTime
{
get => ListMsRec.OrderBy(x => x).FirstOrDefault();
}
/// <summary>
/// numero registrazioni disponibili
/// </summary>
public int NumCall
{
get => ListMsRec.Count();
}
#endregion Public Properties
}
#endregion Public Classes
#region Private Fields
/// <summary>
/// Dizionario di dati statistici accumulati
/// </summary>
private Dictionary<string, RecordData> TrackData = new Dictionary<string, RecordData>();
#endregion Private Fields
}
}
+76 -9
View File
@@ -1052,6 +1052,8 @@ namespace MP.Data.Services
/// <returns></returns>
public async Task<List<Macchine>> MacchineByMatrOper(int MatrOpr)
{
int rndWait = rnd.Next(0, 2);
await Task.Delay(rndWait);
// setup parametri costanti
string source = "DB";
Stopwatch sw = new Stopwatch();
@@ -1059,7 +1061,10 @@ namespace MP.Data.Services
List<Macchine> result = new List<Macchine>();
// cerco in redis...
string currKey = $"{redisBaseKey}:MachByMatOp:{MatrOpr}";
RedisValue rawData = await redisDb.StringGetAsync(currKey);
#if false
RedisValue rawData = await redisDb.StringGetAsync(currKey);
#endif
RedisValue rawData = redisDb.StringGet(currKey);
//if (!string.IsNullOrEmpty($"{rawData}"))
if (rawData.HasValue)
{
@@ -1071,14 +1076,26 @@ namespace MP.Data.Services
result = dbTabController.MacchineByMatrOper(MatrOpr);
// serializzo e salvo...
rawData = JsonConvert.SerializeObject(result);
await redisDb.StringSetAsync(currKey, rawData, LongCache);
redisDb.StringSet(currKey, rawData, LongCache);
#if false
await redisDb.StringSetAsync(currKey, rawData, LongCache);
#endif
}
if (result == null)
{
result = new List<Macchine>();
}
sw.Stop();
Log.Debug($"MacchineByMatrOper | {source} | {sw.Elapsed.TotalMilliseconds}ms");
#if false
Log.Debug($"MacchineByMatrOper | {source} | {sw.Elapsed.TotalMilliseconds}ms");
#endif
string callName = $"MacchineByMatrOper.{source}";
int numRec = esCollect.RecordCall(callName, sw.Elapsed.TotalMilliseconds);
if (numRec >= nRecLog)
{
Log.Debug(esCollect.GetCallSum(callName, true));
}
return result;
}
@@ -1331,6 +1348,11 @@ namespace MP.Data.Services
}
}
/// <summary>
/// gestore collezione statistiche esecuzione x logging
/// </summary>
private ExecStatsCollector esCollect = new ExecStatsCollector();
/// <summary>
/// ODL da key
/// </summary>
@@ -1375,7 +1397,15 @@ namespace MP.Data.Services
result = new ODLExpModel();
}
sw.Stop();
Log.Debug($"OdlByIdx | {idxOdl} | {source} | {sw.Elapsed.TotalMilliseconds}ms");
#if false
Log.Debug($"OdlByIdx | {idxOdl} | {source} | {sw.Elapsed.TotalMilliseconds}ms");
#endif
string callName = $"OdlByIdx.{source}";
int numRec = esCollect.RecordCall(callName, sw.Elapsed.TotalMilliseconds);
if (numRec >= nRecLog)
{
Log.Debug(esCollect.GetCallSum(callName, true));
}
return result;
}
@@ -1449,7 +1479,15 @@ namespace MP.Data.Services
result = new ODLExpModel();
}
sw.Stop();
Log.Debug($"OdlCurrByMacc | {source} | {idxMacchina} | {sw.Elapsed.TotalMilliseconds}ms");
#if false
Log.Debug($"OdlCurrByMacc | {source} | {idxMacchina} | {sw.Elapsed.TotalMilliseconds}ms");
#endif
string callName = $"OdlCurrByMacc.{source}";
int numRec = esCollect.RecordCall(callName, sw.Elapsed.TotalMilliseconds);
if (numRec >= nRecLog)
{
Log.Debug(esCollect.GetCallSum(callName, true));
}
}
else
{
@@ -2019,7 +2057,15 @@ namespace MP.Data.Services
result = new PODLExpModel();
}
sw.Stop();
Log.Debug($"PODL_getByKey | {idxPODL} | {source} | {sw.Elapsed.TotalMilliseconds}ms");
#if false
Log.Debug($"PODL_getByKey | {idxPODL} | {source} | {sw.Elapsed.TotalMilliseconds}ms");
#endif
string callName = $"PODL_getByKey.{source}";
int numRec = esCollect.RecordCall(callName, sw.Elapsed.TotalMilliseconds);
if (numRec >= nRecLog)
{
Log.Debug(esCollect.GetCallSum(callName, true));
}
return result;
}
@@ -2990,6 +3036,8 @@ namespace MP.Data.Services
/// <returns></returns>
public async Task<StatoProdModel> StatoProdMacchina(string idxMacchina, DateTime dtReq)
{
int rndWait = rnd.Next(0, 2);
await Task.Delay(rndWait);
// setup parametri costanti
string source = "DB";
Stopwatch sw = new Stopwatch();
@@ -2997,7 +3045,10 @@ namespace MP.Data.Services
StatoProdModel? result = new StatoProdModel();
// cerco in redis...
string currKey = $"{redisBaseKey}:StatoProd:{idxMacchina}:{dtReq:HHmm}";
RedisValue rawData = await redisDb.StringGetAsync(currKey);
RedisValue rawData = redisDb.StringGet(currKey);
#if false
RedisValue rawData = await redisDb.StringGetAsync(currKey);
#endif
//if (!string.IsNullOrEmpty($"{rawData}"))
if (rawData.HasValue)
{
@@ -3009,17 +3060,33 @@ namespace MP.Data.Services
result = dbTabController.StatoProdMacchina(idxMacchina, dtReq);
// serializzo e salvo...
rawData = JsonConvert.SerializeObject(result);
await redisDb.StringSetAsync(currKey, rawData, UltraFastCache);
redisDb.StringSet(currKey, rawData, UltraFastCache);
#if false
await redisDb.StringSetAsync(currKey, rawData, UltraFastCache);
#endif
}
if (result == null)
{
result = new StatoProdModel();
}
sw.Stop();
Log.Debug($"StatoProdMacchina | {source} | {sw.Elapsed.TotalMilliseconds}ms");
#if false
Log.Debug($"StatoProdMacchina | {source} | {sw.Elapsed.TotalMilliseconds}ms");
#endif
string callName = $"StatoProdMacchina.{source}";
int numRec = esCollect.RecordCall(callName, sw.Elapsed.TotalMilliseconds);
if (numRec >= nRecLog)
{
Log.Debug(esCollect.GetCallSum(callName, true));
}
return result;
}
/// <summary>
/// numero minimo di record per cui iniziare fase di log
/// </summary>
private int nRecLog = 10;
/// <summary>
/// Turno macchina
/// </summary>