Files
elma/ELMA/LogAnalyzer.cs
T
2022-07-14 12:41:21 +02:00

518 lines
16 KiB
C#

using AppData;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace ELMA
{
public partial class LogAnalyzer : Form
{
#region Public Fields
/// <summary>
/// Oggetto conf setup
/// </summary>
public eSetup activeSetup = new eSetup();
#endregion Public Fields
#region Public Constructors
public LogAnalyzer()
{
InitializeComponent();
myInit();
startTimers();
}
#endregion Public Constructors
#region Protected Properties
protected string selApp
{ get { return listApp.SelectedItem.ToString(); } }
protected string selHost
{ get { return listHost.SelectedItem.ToString(); } }
protected string selStatus
{
get
{
string answ = "";
if (chkStatus.Checked)
{
if (listStatus.SelectedItem != null)
{
answ = listStatus.SelectedItem.ToString();
}
}
return answ;
}
}
protected string selType
{ get { return listType.SelectedItem.ToString(); } }
protected string selUser
{ get { return listUsers.SelectedItem.ToString(); } }
#endregion Protected Properties
#region Protected Methods
/// <summary>
/// Calcola path applicazione partendo da bassePath
/// </summary>
/// <param name="application"></param>
/// <returns></returns>
protected string getAppPath(string application)
{
return application.Replace(activeSetup.appBasePath, "");
}
#endregion Protected Methods
#region Private Fields
private ElmahModel model = new ElmahModel();
#endregion Private Fields
#region Private Methods
/// <summary>
/// Elimino record selezionati
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnDeleteSel_Click(object sender, EventArgs e)
{
deleteSelRows().ConfigureAwait(false);
}
private void checkFilterVisibility()
{
// Verifico TUTTI i filtri
listApp.Enabled = chkApp.Checked && listApp.Items.Count > 0;
listHost.Enabled = chkHost.Checked && listHost.Items.Count > 0;
listStatus.Enabled = chkStatus.Checked && listStatus.Items.Count > 0;
listType.Enabled = chkType.Checked && listType.Items.Count > 0;
listUsers.Enabled = chkUsers.Checked && listUsers.Items.Count > 0;
}
private void chkApp_CheckedChanged(object sender, EventArgs e)
{
doUpdate();
}
private void chkHost_CheckedChanged(object sender, EventArgs e)
{
doUpdate();
}
private void chkStatus_CheckedChanged(object sender, EventArgs e)
{
doUpdate();
}
private void chkType_CheckedChanged(object sender, EventArgs e)
{
doUpdate();
}
private void chkUsers_CheckedChanged(object sender, EventArgs e)
{
doUpdate();
}
private void currentConfigToolStripMenuItem_Click(object sender, EventArgs e)
{
ConfigMan currConfig = new ConfigMan();
currConfig.currSetup = activeSetup;
currConfig.Owner = this;
currConfig.doUpdate();
currConfig.Show();
}
private void deleteRecordFiltered()
{
// elimino 1:1 da selezione
foreach (var item in getFiltData())
{
model.ELMAH_Error.Remove(item);
}
// salvo
model.SaveChangesAsync();
// aggiorno!!
setupFilterData();
doUpdate();
}
private async Task deleteSelRows()
{
List<string> selIdx = new List<string>();
Guid ErrorId;
// num max x ogni step...
int maxBatch = 500;
// SOLO SE selezionato in dgv...
int totRow = ErrorsDGV.SelectedRows.Count;
if (totRow > 0)
{
foreach (DataGridViewRow riga in ErrorsDGV.SelectedRows)
{
selIdx.Add($"'{((ELMAH_Error)riga.DataBoundItem).ErrorId}'");
#if false
// chiudo!
ErrorId = ((ELMAH_Error)riga.DataBoundItem).ErrorId;
try
{
model.ELMAH_Error.Remove((ELMAH_Error)riga.DataBoundItem);
}
catch
{ }
#endif
// verifico se cancellare
if (selIdx.Count >= maxBatch)
{
await deleteList(selIdx);
// resetto
selIdx = new List<string>();
}
}
}
if (selIdx.Count > 0)
{
await deleteList(selIdx);
}
// aggiorno!!
doUpdate();
}
private async Task deleteList(List<string> selIdx)
{
// scrivo query x cancellare tutti...
string stringOfIds = string.Join(",", selIdx);
await model.Database.ExecuteSqlCommandAsync($"DELETE FROM ELMAH_Error WHERE ErrorId IN ({stringOfIds})");
// salvo/eseguo
await model.SaveChangesAsync();
}
/// <summary>
/// Aggiornamento visualizzazioni
/// </summary>
private void doUpdate()
{
checkFilterVisibility();
updateSelection();
}
private void ErrorsDGV_CellDoubleClick(object sender, DataGridViewCellEventArgs e)
{
// seleziono riga
}
private void ErrorsDGV_DoubleClick(object sender, EventArgs e)
{
// recupero valore...
Guid ErrorId;
string appPath = "";
string pageUrl = "";
// SOLO SE selezionato in dgv...
if (ErrorsDGV.SelectedRows.Count > 0)
{
foreach (DataGridViewRow riga in ErrorsDGV.SelectedRows)
{
// recupero dati
ErrorId = ((ELMAH_Error)riga.DataBoundItem).ErrorId;
appPath = getAppPath(((ELMAH_Error)riga.DataBoundItem).Application);
// SE appPAth !="" accodo...
if (!string.IsNullOrEmpty(appPath))
{
pageUrl = $"{activeSetup.baseUrl}/{appPath}/elmah.axd/detail?id={ErrorId}";
}
else
{
pageUrl = $"{activeSetup.baseUrl}/elmah.axd/detail?id={ErrorId}";
}
// mostro form
var newBrowser = new WBrowser();
newBrowser.pageUrl = pageUrl;
newBrowser.Show();
}
}
}
private int allRecord = 0;
private List<ELMAH_Error> getFiltData()
{
var dbSet = model.ELMAH_Error;
int statusCode = 0;
int.TryParse(selStatus, out statusCode);
string selApp = listApp.SelectedItem.ToString();
// inizio azione filtraggio..
IQueryable<ELMAH_Error> subset = dbSet.Where(x => x.Sequence > 0);
if (chkApp.Checked)
{
subset = subset.Where(x => x.Application == selApp);
}
if (chkHost.Checked)
{
subset = subset.Where(x => x.Host == selHost);
}
if (chkStatus.Checked)
{
subset = subset.Where(x => x.StatusCode == statusCode);
}
if (chkType.Checked)
{
subset = subset.Where(x => x.Type == selType);
}
if (chkUsers.Checked)
{
subset = subset.Where(x => x.User == selUser);
}
int maxRec = 100;
int.TryParse(txtMaxRow.Text, out maxRec);
// calcolo tutti ir ecord filtrati...
allRecord = subset.Count();
// se + di maxRec --> filtro
if (allRecord > maxRec)
{
subset = subset.Take(maxRec);
}
return subset.OrderByDescending(x => x.TimeUtc).ToList();
}
private void listApp_SelectedIndexChanged(object sender, EventArgs e)
{
if (chkApp.Checked)
doUpdate();
}
private void listHost_SelectedIndexChanged(object sender, EventArgs e)
{
if (chkHost.Checked)
doUpdate();
}
private void listStatus_SelectedIndexChanged(object sender, EventArgs e)
{
if (chkStatus.Checked)
doUpdate();
}
private void listType_SelectedIndexChanged(object sender, EventArgs e)
{
if (chkType.Checked)
doUpdate();
}
private void listUsers_SelectedIndexChanged(object sender, EventArgs e)
{
if (chkUsers.Checked)
doUpdate();
}
/// <summary>
/// Carica la conf corrente
/// </summary>
/// <param name="filePath"></param>
private void loadConf(string filePath)
{
if (File.Exists(filePath))
{
try
{
activeSetup = JsonConvert.DeserializeObject<eSetup>(File.ReadAllText(filePath));
}
catch
{ }
}
}
private void loadToolStripMenuItem_Click(object sender, EventArgs e)
{
// salvo la conf corrente...
OpenFileDialog oFileDialog = new OpenFileDialog();
oFileDialog.DefaultExt = "jset";
oFileDialog.Filter = "Conf files (*.jset)|*.jset|All files (*.*)|*.*";
oFileDialog.InitialDirectory = Utils.confDir;
oFileDialog.RestoreDirectory = true;
if (oFileDialog.ShowDialog() == DialogResult.OK)
{
// carico
loadConf(oFileDialog.FileName);
}
}
private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
{
timerMain.Stop();
}
private void myInit()
{
setupConfig();
setupFilterData();
doUpdate();
}
private void resetFilter()
{
chkApp.Checked = false;
chkHost.Checked = false;
chkStatus.Checked = false;
chkType.Checked = false;
chkUsers.Checked = false;
}
/// <summary>
/// Salva conf corrente sul file indicato
/// </summary>
/// <param name="filePath"></param>
private void saveConf(string filePath)
{
// .. e lo salvo...
string rawData = JsonConvert.SerializeObject(activeSetup, Formatting.Indented);
File.WriteAllText(filePath, rawData);
}
private void saveToolStripMenuItem_Click(object sender, EventArgs e)
{
// salvo la conf corrente...
SaveFileDialog sFileDialog = new SaveFileDialog();
sFileDialog.DefaultExt = "jset";
sFileDialog.Filter = "Conf files (*.jset)|*.jset|All files (*.*)|*.*";
sFileDialog.InitialDirectory = Utils.confDir;
sFileDialog.RestoreDirectory = true;
if (sFileDialog.ShowDialog() == DialogResult.OK)
{
// salvo!
string rawData = JsonConvert.SerializeObject(activeSetup, Formatting.Indented);
saveConf(sFileDialog.FileName);
}
}
/// <summary>
/// Setup configurazione da std file
/// </summary>
private void setupConfig()
{
// cerco il file json di config
string filePath = $"{Utils.confDir}\\{Utils.setupFile}";
loadConf(filePath);
if (string.IsNullOrEmpty(activeSetup.name))
{
// se non lo trovo creo setu...
activeSetup = new eSetup()
{
name = "standard",
userName = "sa",
passwd = "keyhammer16",
SSIP = false,
sqlServer = "SQL2016DEV",
appBasePath = "/LM/W3SVC/1/ROOT",
baseUrl = "https://localhost:44388"
};
saveConf(filePath);
}
}
private void setupFilterData()
{
// resetto dati
listApp.Items.Clear();
listHost.Items.Clear();
listStatus.Items.Clear();
listType.Items.Clear();
listUsers.Items.Clear();
// carico DB con filtri
var setApp = model.ELMAH_Error
.Select(e => new { e.Application })
.Distinct()
.ToList();
foreach (var item in setApp)
{
listApp.Items.Add(item.Application);
}
var setHost = model.ELMAH_Error
.Select(e => new { e.Host })
.Distinct()
.ToList();
foreach (var item in setHost)
{
listHost.Items.Add(item.Host);
}
var setStatus = model.ELMAH_Error
.Select(e => new { e.StatusCode })
.Distinct()
.ToList();
foreach (var item in setStatus)
{
listStatus.Items.Add(item.StatusCode);
}
var setType = model.ELMAH_Error
.Select(e => new { e.Type })
.Distinct()
.ToList();
foreach (var item in setType)
{
listType.Items.Add(item.Type);
}
var setUser = model.ELMAH_Error
.Select(e => new { e.User })
.Distinct()
.ToList();
//var setUser = dbFilt.Where(x => x.Cat == "User").ToList();
foreach (var item in setUser)
{
listUsers.Items.Add(item.User);
}
listApp.SelectedIndex = 0;
listHost.SelectedIndex = 0;
listStatus.SelectedIndex = 0;
listType.SelectedIndex = 0;
listUsers.SelectedIndex = 0;
}
private void startTimers()
{
timerMain.Start();
}
private void timerMain_Tick(object sender, EventArgs e)
{
#if false
setupFilterData();
doUpdate();
#endif
}
private void txtMaxRow_TextChanged(object sender, EventArgs e)
{
doUpdate();
}
private void updateSelection()
{
List<ELMAH_Error> subset = getFiltData();
this.bsErrors.DataSource = subset;
for (int i = 0; i < ErrorsDGV.Columns.Count - 1; i++)
{
ErrorsDGV.Columns[i].AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;
}
tsslNumRec.Text = $"{subset.Count}/{allRecord} rec";
}
#endregion Private Methods
}
}