LogNetAnalysisControl.cs 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519
  1. using System;
  2. using System.Collections.Generic;
  3. using System.ComponentModel;
  4. using System.Drawing;
  5. using System.Data;
  6. using System.Linq;
  7. using System.Text;
  8. using System.Windows.Forms;
  9. using System.Text.RegularExpressions;
  10. namespace HslCommunication.LogNet
  11. {
  12. /// <summary>
  13. /// 一个用于日志分析的控件
  14. /// </summary>
  15. public partial class LogNetAnalysisControl : UserControl
  16. {
  17. /// <summary>
  18. /// 实例化一个控件信息
  19. /// </summary>
  20. public LogNetAnalysisControl()
  21. {
  22. InitializeComponent();
  23. }
  24. private void LogNetAnalysisControl_Load(object sender, EventArgs e)
  25. {
  26. }
  27. private string m_LogSource = string.Empty;
  28. /// <summary>
  29. /// 设置日志的数据源
  30. /// </summary>
  31. /// <param name="logSource">直接从日志文件中读到的数据或是来自网络的数据</param>
  32. public void SetLogNetSource(string logSource)
  33. {
  34. m_LogSource = logSource;
  35. SetLogNetSourceView();
  36. }
  37. private void SetLogNetSourceView()
  38. {
  39. if (!string.IsNullOrEmpty(m_LogSource))
  40. {
  41. AnalysisLogSource(DateTime.MinValue, DateTime.MaxValue, LogNetManagment.TextAll);
  42. if (selectButton != null) selectButton.Selected = false;
  43. selectButton = userButton_All;
  44. }
  45. }
  46. /// <summary>
  47. /// 从现有的日志中筛选数据
  48. /// </summary>
  49. /// <param name="degree"></param>
  50. private void FilterLogSource(string degree)
  51. {
  52. if (!string.IsNullOrEmpty(m_LogSource))
  53. {
  54. DateTime start;
  55. if (!DateTime.TryParse(textBox2.Text, out start))
  56. {
  57. MessageBox.Show("起始时间的格式不正确,请重新输入");
  58. return;
  59. }
  60. DateTime end;
  61. if (!DateTime.TryParse(textBox3.Text,out end))
  62. {
  63. MessageBox.Show("结束时间的格式不正确,请重新输入");
  64. return;
  65. }
  66. AnalysisLogSource(start, end, degree);
  67. }
  68. }
  69. /// <summary>
  70. /// 底层的数据分析筛选
  71. /// </summary>
  72. /// <param name="start"></param>
  73. /// <param name="end"></param>
  74. /// <param name="degree"></param>
  75. private void AnalysisLogSource(DateTime start,DateTime end,string degree)
  76. {
  77. if (!string.IsNullOrEmpty(m_LogSource))
  78. {
  79. StringBuilder sb = new StringBuilder();
  80. List<Match> collection = new List<Match>(Regex.Matches(m_LogSource, "\u0002\\[[^\u0002]+").OfType<Match>());
  81. int debug = 0;
  82. int info = 0;
  83. int warn = 0;
  84. int error = 0;
  85. int fatal = 0;
  86. int all = 0;
  87. List<DateTime> list = new List<DateTime>();
  88. for (int i = 0; i < collection.Count; i++)
  89. {
  90. Match m = collection[i];
  91. string deg = m.Value.Substring(2, 2);
  92. DateTime dateTime = Convert.ToDateTime(m.Value.Substring(6, 19));
  93. if (start == DateTime.MinValue)
  94. {
  95. if (i == 0)
  96. {
  97. // 提取第一个时间
  98. textBox2.Text = m.Value.Substring(6, 19);
  99. }
  100. if (i == collection.Count - 1)
  101. {
  102. // 提取最后一个时间
  103. textBox3.Text = m.Value.Substring(6, 19);
  104. }
  105. }
  106. if (start <= dateTime && dateTime <= end)
  107. {
  108. if (checkBox1.Checked)
  109. {
  110. // 正则表达式过滤
  111. if (!Regex.IsMatch(m.Value, textBox4.Text))
  112. {
  113. continue;
  114. }
  115. }
  116. switch (deg)
  117. {
  118. case LogNetManagment.TextDebug:
  119. {
  120. debug++;
  121. break;
  122. }
  123. case LogNetManagment.TextInfo:
  124. {
  125. info++;
  126. break;
  127. }
  128. case LogNetManagment.TextWarn:
  129. {
  130. warn++;
  131. break;
  132. }
  133. case LogNetManagment.TextError:
  134. {
  135. error++;
  136. break;
  137. }
  138. case LogNetManagment.TextFatal:
  139. {
  140. fatal++;
  141. break;
  142. }
  143. default: break;
  144. }
  145. all++;
  146. if (degree == LogNetManagment.TextAll || degree == deg)
  147. {
  148. sb.Append(m.Value.Substring(1));
  149. list.Add(dateTime);
  150. }
  151. }
  152. }
  153. userButton_Debug.UIText = $"{LogNetManagment.TextDebug} ({debug})";
  154. userButton_Info.UIText = $"{LogNetManagment.TextInfo} ({info})";
  155. userButton_Warn.UIText = $"{LogNetManagment.TextWarn} ({warn})";
  156. userButton_Error.UIText = $"{LogNetManagment.TextError} ({error})";
  157. userButton_Fatal.UIText = $"{LogNetManagment.TextFatal} ({fatal})";
  158. userButton_All.UIText = $"{LogNetManagment.TextAll} ({all})";
  159. textBox1.Text = sb.ToString();
  160. listPaint = list;
  161. // 设置图形显示
  162. if (pictureBox1.Width > 10)
  163. {
  164. pictureBox1.Image = PaintData(pictureBox1.Width, pictureBox1.Height);
  165. }
  166. }
  167. }
  168. private HslCommunication.Controls.UserButton selectButton = null;
  169. private void UserButtonSetSelected(Controls.UserButton userButton)
  170. {
  171. if(!ReferenceEquals(selectButton,userButton))
  172. {
  173. if (selectButton != null) selectButton.Selected = false;
  174. userButton.Selected = true;
  175. selectButton = userButton;
  176. }
  177. }
  178. private void userButton_Debug_Click(object sender, EventArgs e)
  179. {
  180. // 调试
  181. UserButtonSetSelected(userButton_Debug);
  182. FilterLogSource(LogNetManagment.TextDebug);
  183. }
  184. private void userButton_Info_Click(object sender, EventArgs e)
  185. {
  186. // 信息
  187. UserButtonSetSelected(userButton_Info);
  188. FilterLogSource(LogNetManagment.TextInfo);
  189. }
  190. private void userButton_Warn_Click(object sender, EventArgs e)
  191. {
  192. // 警告
  193. UserButtonSetSelected(userButton_Warn);
  194. FilterLogSource(LogNetManagment.TextWarn);
  195. }
  196. private void userButton_Error_Click(object sender, EventArgs e)
  197. {
  198. // 错误
  199. UserButtonSetSelected(userButton_Error);
  200. FilterLogSource(LogNetManagment.TextError);
  201. }
  202. private void userButton_Fatal_Click(object sender, EventArgs e)
  203. {
  204. // 致命
  205. UserButtonSetSelected(userButton_Fatal);
  206. FilterLogSource(LogNetManagment.TextFatal);
  207. }
  208. private void userButton_All_Click(object sender, EventArgs e)
  209. {
  210. // 全部
  211. UserButtonSetSelected(userButton_All);
  212. FilterLogSource(LogNetManagment.TextAll);
  213. }
  214. private void userButton_source_Click(object sender, EventArgs e)
  215. {
  216. // 源日志
  217. SetLogNetSourceView();
  218. }
  219. #region 自动绘图块
  220. private List<DateTime> listPaint = new List<DateTime>();
  221. private List<PaintItem> listRender = new List<PaintItem>();
  222. private Bitmap PaintData(int width,int height)
  223. {
  224. if (width < 200) width = 200;
  225. if (height < 100) height = 100;
  226. Bitmap bitmap = new Bitmap(width, height);
  227. Graphics g = Graphics.FromImage(bitmap);
  228. Font font12 = new Font("宋体", 12f);
  229. StringFormat sf = new StringFormat
  230. {
  231. Alignment = StringAlignment.Far,
  232. LineAlignment = StringAlignment.Center,
  233. };
  234. Pen dash = new Pen(Color.LightGray, 1f);
  235. dash.DashStyle = System.Drawing.Drawing2D.DashStyle.Custom;
  236. dash.DashPattern = new float[] { 5, 5 };
  237. g.Clear(Color.White);
  238. if (listPaint.Count <= 5)
  239. {
  240. g.DrawString("数据太少了", font12, Brushes.DeepSkyBlue, new Rectangle(0,0,width, height), sf);
  241. goto P1;
  242. }
  243. int count = (width - 60) / 6;
  244. TimeSpan sp = listPaint.Max() - listPaint.Min();
  245. DateTime datetime_min= listPaint.Min();
  246. double sep = sp.TotalSeconds / count;
  247. int[] counts = new int[count];
  248. for (int i = 0; i < listPaint.Count; i++)
  249. {
  250. TimeSpan timeSpan = listPaint[i] - datetime_min;
  251. int index = (int)(timeSpan.TotalSeconds / sep);
  252. if (index < 0) index = 0;
  253. if (index == count) index--;
  254. counts[index]++;
  255. }
  256. int Max = counts.Max();
  257. int Min = 0;
  258. PaintItem[] list = new PaintItem[count];
  259. for (int i = 0; i < counts.Length; i++)
  260. {
  261. PaintItem item = new PaintItem();
  262. item.Count = counts[i];
  263. item.Start = listPaint[0].AddSeconds(i * sep);
  264. if (i == counts.Length - 1)
  265. {
  266. item.End = listPaint[listPaint.Count - 1];
  267. }
  268. else
  269. {
  270. item.End = listPaint[0].AddSeconds((i + 1) * sep);
  271. }
  272. list[i] = item;
  273. }
  274. listRender = new List<PaintItem>(list);
  275. // 左边空50,右边空10,上面20,下面30
  276. int left = 50;
  277. int right = 10;
  278. int up = 20;
  279. int down = 30;
  280. g.DrawLine(Pens.DimGray, left, up - 10, left, height - down);
  281. g.DrawLine(Pens.DimGray, left, height - down + 1, width - right, height - down + 1);
  282. g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
  283. // 绘制箭头
  284. BasicFramework.SoftPainting.PaintTriangle(g, Brushes.DimGray, new Point(left, up - 10), 5, BasicFramework.GraphDirection.Upward);
  285. g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.None;
  286. int degree = 8;
  287. if (height < 500)
  288. {
  289. if (Max < 15 && Max > 1) degree = Max;
  290. }
  291. else if (height < 700)
  292. {
  293. if (Max < 25 && Max > 1) degree = Max;
  294. else
  295. {
  296. degree = 16;
  297. }
  298. }
  299. else
  300. {
  301. if (Max < 40 && Max > 1) degree = Max;
  302. else degree = 24;
  303. }
  304. // 绘制刻度
  305. BasicFramework.SoftPainting.PaintCoordinateDivide(g, Pens.DimGray, dash, font12, Brushes.DimGray,
  306. sf, degree, Max, Min, width, height, left, right, up, down);
  307. sf.Alignment = StringAlignment.Center;
  308. // 绘制总数
  309. g.DrawString("Totle: " + listPaint.Count, font12, Brushes.DodgerBlue,
  310. new RectangleF(left, 0, width - left - right, up), sf);
  311. int paint_x = left + 2;
  312. for (int i = 0; i < list.Length; i++)
  313. {
  314. // 计算绘制位置
  315. float location = BasicFramework.SoftPainting.ComputePaintLocationY(Max, Min, height - up - down, list[i].Count) + up;
  316. RectangleF rectangleF = new RectangleF(paint_x, location, 5, height - down - location);
  317. if (rectangleF.Height <= 0 && list[i].Count > 0)
  318. {
  319. rectangleF = new RectangleF(paint_x, height - down - 1, 5, 1);
  320. }
  321. g.FillRectangle(Brushes.Tomato, rectangleF);
  322. paint_x += 6;
  323. }
  324. g.DrawLine(Pens.DimGray, paint_x, up - 10, paint_x, height - down);
  325. g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
  326. BasicFramework.SoftPainting.PaintTriangle(g, Brushes.DimGray, new Point(paint_x, up - 10), 5, BasicFramework.GraphDirection.Upward);
  327. g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.None;
  328. P1:
  329. sf.Dispose();
  330. font12.Dispose();
  331. dash.Dispose();
  332. g.Dispose();
  333. return bitmap;
  334. }
  335. #endregion
  336. private class PaintItem
  337. {
  338. public DateTime Start { get; set; }
  339. public DateTime End { get; set; }
  340. public int Count { get; set; }
  341. }
  342. private bool IsMouseEnter { get; set; }
  343. private PaintItem ClickSelected { get; set; }
  344. private Point pointMove { get; set; }
  345. private StringFormat stringFormat = new StringFormat
  346. {
  347. Alignment = StringAlignment.Center,
  348. LineAlignment = StringAlignment.Center,
  349. };
  350. private void pictureBox1_Paint(object sender, PaintEventArgs e)
  351. {
  352. if (IsMouseEnter)
  353. {
  354. if (ClickSelected != null)
  355. {
  356. if (pictureBox1.Width > 100)
  357. {
  358. string text = ClickSelected.Start.ToString("yyyy-MM-dd HH:mm:ss") + " - " +
  359. ClickSelected.End.ToString("yyyy-MM-dd HH:mm:ss") + Environment.NewLine + "Count:" +
  360. ClickSelected.Count;
  361. e.Graphics.DrawString(text, Font, Brushes.DimGray, new Rectangle(50, pictureBox1.Height - 27, pictureBox1.Width - 60, 30), stringFormat);
  362. // 绘制位置提示线
  363. e.Graphics.DrawLine(Pens.DeepPink, pointMove.X, 15, pointMove.X, pictureBox1.Height - 30);
  364. }
  365. }
  366. }
  367. }
  368. private void pictureBox1_MouseEnter(object sender, EventArgs e)
  369. {
  370. IsMouseEnter = true;
  371. }
  372. private void pictureBox1_MouseLeave(object sender, EventArgs e)
  373. {
  374. IsMouseEnter = false;
  375. pictureBox1.Refresh();
  376. }
  377. private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
  378. {
  379. if (IsMouseEnter)
  380. {
  381. if (e.Y > 20 &&
  382. e.Y < pictureBox1.Height - 30 &&
  383. e.X > 51 &&
  384. e.X < pictureBox1.Width - 10)
  385. {
  386. if ((e.X - 52) % 6 == 5) return;
  387. int index = (e.X - 52) / 6;
  388. if (index < listRender.Count)
  389. {
  390. pointMove = e.Location;
  391. ClickSelected = listRender[index];
  392. pictureBox1.Refresh();
  393. }
  394. }
  395. }
  396. }
  397. private void pictureBox1_SizeChanged(object sender, EventArgs e)
  398. {
  399. // 设置图形显示
  400. if (pictureBox1.Width > 10)
  401. {
  402. pictureBox1.Image = PaintData(pictureBox1.Width, pictureBox1.Height);
  403. }
  404. }
  405. private void pictureBox1_DoubleClick(object sender, EventArgs e)
  406. {
  407. if (IsMouseEnter)
  408. {
  409. if (pointMove.Y > 20 &&
  410. pointMove.Y < pictureBox1.Height - 30 &&
  411. pointMove.X > 51 &&
  412. pointMove.X < pictureBox1.Width - 10)
  413. {
  414. if (selectButton != null)
  415. {
  416. if ((ClickSelected.End - ClickSelected.Start).TotalSeconds > 3)
  417. {
  418. textBox2.Text = ClickSelected.Start.ToString("yyyy-MM-dd HH:mm:ss");
  419. textBox3.Text = ClickSelected.End.ToString("yyyy-MM-dd HH:mm:ss");
  420. AnalysisLogSource(ClickSelected.Start, ClickSelected.End, selectButton.UIText.Substring(0, 2));
  421. }
  422. }
  423. }
  424. }
  425. }
  426. }
  427. }