栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

C#日志模块 07

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

C#日志模块 07

C#日志模块 日志模块是生产过程中记录,软件运行信息的重要文件,包含了软件的运行日志,警告日志,和错误日志。方便事后程序员排查问题

首先要确定需要的参数,ID是必须的,其次日志得含有日期,标题,内容,日志类型。查询日志一般来说是通过开始时间,结束时间,日志类型来查询。
model层建立LogsInfo

public class LogsInfo
    {
        public int LId { get; set; }
        public string LDataTime { get; set; }
        public string LTitle { get; set; }
        public string LContent { get; set; }
        public LogsType LType { get; set; }
    }
    public enum LogsType
    {
       所有信息,
       错误信息,
       警告信息,
       运行信息
    }
    public class LogsQuery
    {
        public DateTime starttime { get; set; }
        public DateTime endtime { get; set; }
        public LogsType LType { get; set; }
    }

这里因为日志一般数据量很大,且保存时间较久,这里不使用sqlite,我们改用mysql
通过上面参数设计mysql表格

Dal层建立mysql通用方法类

public class MysqlHelper
    {
        private static readonly string conStr = "Database='mydatabase';Data Source='localhost';Port='3360';User Id='root';Password='123456';charset='utf8';pooling=true";
        /// 
        /// 1、执行增(insert) 删(delete) 改(update) 的方法
        /// 
        /// 
        /// 
        /// 
        public static int ExecuteNonQuery(string sql, params MySqlParameter[] pms)
        {
            using (MySqlConnection con = new MySqlConnection(conStr))
            {
                using (MySqlCommand cmd = new MySqlCommand(sql, con))
                {
                    if (pms.Length>0)
                    {
                        if (pms[0] != null)
                        {
                            cmd.Parameters.AddRange(pms);
                        }
                    }
                    con.Open();
                    return cmd.ExecuteNonQuery();
                }
            }
        }

        /// 
        /// 2、执行查询,返回单个值的方法
        /// 
        /// 
        /// 
        /// 
        public static object ExecuteScalar(string sql, params MySqlParameter[] pms)
        {
            using (MySqlConnection con = new MySqlConnection(conStr))
            {
                using (MySqlCommand cmd = new MySqlCommand(sql, con))
                {
                    if (pms != null)
                    {
                        cmd.Parameters.AddRange(pms);
                    }
                    con.Open();
                    return cmd.ExecuteScalar();
                }
            }
        }

        /// 
        /// 3、执行查询,返回多行多列的方法
        /// 
        /// 
        /// 
        /// 
        public static MySqlDataReader ExecuteReader(string sql, params MySqlParameter[] pms)
        {
            MySqlConnection con = new MySqlConnection(conStr);
            using (MySqlCommand cmd = new MySqlCommand(sql, con))
            {
                if (pms != null)
                {
                    cmd.Parameters.AddRange(pms);
                }
                try
                {
                    con.Open();
                    //这个枚举参数,表示将来使用完毕reader后,在关闭reader的
                    //同时,在sqldatareader内部会将关联的connection对象也关闭掉
                    return cmd.ExecuteReader
                        (System.Data.CommandBehavior.CloseConnection);
                }
                catch
                {
                    con.Close();
                    con.Dispose();
                    throw;
                }

            }

        }

        /// 
        /// 4、查询数据返回DataTable
        /// 
        /// 
        /// 
        /// 
        public static DataTable ExecuteDataTable(string sql, params MySqlParameter[] pms)
        {
            try
            {
                //构造连接对象
                using (MySqlConnection conn = new MySqlConnection(conStr))
                {
                    //构造桥接器对象
                    MySqlDataAdapter adapter = new MySqlDataAdapter(sql, conn);
                    //加参数查找
                    if (pms[0] != null)
                    {
                        adapter.SelectCommand.Parameters.AddRange(pms);
                    }
                    //数据表对象
                    DataTable table = new DataTable();
                    //将数据存到table中
                    adapter.Fill(table);
                    //返回数据表
                    return table;

                }
            }
            catch (Exception ex)
            {
                DataTable table = new DataTable();
                return table;

            }

        }

建立好通用方法后,我们接着在Dal声名类

public class LogsDal
    {
        /// 
        /// 插入
        /// 
        /// 
        /// 
        public int Insert(LogsInfo li)
        {
            //构造sql语句
            string sql =
                "insert into Logs(LDataTime,LTitle,LContent,LType) values(@datatime,@title,@content,@type)";
            //数组的初始化器
            MySqlParameter[] ps =
                {
                   new MySqlParameter("@datatime",li.LDataTime),
                   new MySqlParameter("@title",li.LTitle),
                   new MySqlParameter("@content",li.LContent),
                   new MySqlParameter("@type",li.LType.ToString()),
                };
            //执行
            return MysqlHelper.ExecuteNonQuery(sql, ps);
        }
        /// 
        /// 删除n天以外的日志
        /// 
        /// 
        /// 
        public int DeleteTime(int date)
        {
            ///DELETE FROM 表名 WHERe 时间字段 BETWEEN 开始时间 AND 结束时间
            ///DELETe FROM 表名 WHERe 时间字段>=开始时间 AND 时间字段<=结束时间
            string sql = "delete From `logs` where DATE(LDataTime) <= DATE(DATE_SUB(NOW(),INTERVAL @time day)) ";
            MySqlParameter[] ps =
                {
                   new MySqlParameter("@time",date)
                };
            return MysqlHelper.ExecuteNonQuery(sql, ps);

        }
        /// 
        /// 清空表
        /// 
        /// 
        public int EmptyTable()
        {
            string sql = "truncate Logs";
            return MysqlHelper.ExecuteNonQuery(sql);
        }
        /// 
        /// 删除在n-k之间的数据
        /// 
        /// 
        /// 
        public int Delete(DateTime startdate,DateTime endtime)
        {
            ///DELETE FROM 表名 WHERe 时间字段 BETWEEN 开始时间 AND 结束时间
            ///DELETe FROM 表名 WHERe 时间字段>=开始时间 AND 时间字段<=结束时间
            string sql = "delete From `logs` where LDataTime between @starttime and @endtime";
            MySqlParameter[] ps =
                {
                   new MySqlParameter("@starttime",startdate),
                   new MySqlParameter("@endtime",endtime)
                };
            return MysqlHelper.ExecuteNonQuery(sql, ps);

        }
        /// 
        /// 通过时间来查找数据
        /// 包含开始时间,结束时间,信息类型
        /// 
        /// 
        public List Getlist(LogsQuery lq)
        {
            List list = new List();
            List sqllist = new List();
            string sql = "select * from Logs where LDataTime>= @starttime and LDataTime<=@endtime";
            sqllist.Add(new MySqlParameter("@starttime", lq.starttime));
            sqllist.Add(new MySqlParameter("@endtime", lq.endtime));
            if (lq.LType != LogsType.所有信息)
            {
                sql = String.Concat(sql, " and LType=@type");
                sqllist.Add(new MySqlParameter("@type", lq.LType.ToString()));
            }
            using (MySqlDataReader reader = MysqlHelper.ExecuteReader(sql, sqllist.ToArray()))
            {
                if (reader.HasRows)
                {
                    while (reader.Read())
                    {
                        LogsInfo model = new LogsInfo()
                        {
                            LId = reader.GetInt32(0),
                            LDataTime = reader.GetString(1),
                            LTitle = reader.GetString(2),
                            LContent = reader.GetString(3),
                            LType = (LogsType)Enum.Parse(typeof(LogsType), reader.GetString(4))
                        };
                        list.Add(model);
                    }
                }
            }
            return list;
        }
    }

这里由于要对查询出来的数据进行整理分页
所以在COMMON层声名

public class LogsHelper
    {
        /// 
        /// 把一个集合分割成一个集合为num个数的集合
        /// 
        /// 
        /// 
        /// 
        /// 
        public static List> SpiltList(List Lists, int num) //where T:class
        {
            List> fz = new List>();
            //组数
            int GroupNum;
            //元素数量大于等于 一组的个数
            if (Lists.Count >= num)
            {
                if (Lists.Count % num == 0)
                {
                    GroupNum = Lists.Count / num;
                }
                else
                {
                    GroupNum = Lists.Count / num + 1;
                }
                //给每一组分配元素
                for (int i = 0; i < GroupNum; i++)
                {
                    List cList = new List();
                    if (i + 1 == GroupNum)
                    {
                        cList = Lists.Skip(num * i).ToList();
                    }
                    else
                    {
                        cList = Lists.Skip(num * i).Take(num).ToList();
                    }
                    fz.Add(cList);
                }
            }
            else
            {
                fz.Add(Lists);//元素数量小于分组数量
            }
            return fz;
        }
    }

随后我们在Bll层建立LogsBll

    #region << 版 本 注 释 >>
    
    #endregion
    public class LogsBll
    {
        LogsDal Dal = new LogsDal();
        /// 
        /// 私有化构造函数
        /// 
        private LogsBll()
        {

        }
        /// 
        /// 声名一个静态变量
        /// 
        private static LogsBll LoList;
        /// 
        /// 单例模式
        /// 
        /// 
        public static LogsBll Create()
        {
            if (LoList == null)
            {
                LoList = new LogsBll();
            }
            return LoList;
        }
        /// 
        /// 获得日志集合
        /// 
        /// 
        private List GetList(LogsQuery lq)
        {
            return Dal.Getlist(lq);
        }
        /// 
        /// 插入一行数据
        /// 
        /// 
        /// 
        public bool Add(LogsInfo li)
        {
            return Dal.Insert(li) > 0;
        }
        /// 
        /// 移除
        /// 
        /// 
        /// 
        public bool Remove(int date)
        {
            return Dal.DeleteTime(date) > 0;
        }
        /// 
        /// 清空表格
        /// 
        /// 
        public bool EmptyTable()
        {
            return Dal.EmptyTable() > 0;

        }
        /// 
        /// 删除在n-k时间之间的数据
        /// 
        /// 
        /// 
        /// 
        public bool Delete(DateTime startdate, DateTime endtime)
        {
            return Dal.Delete(startdate, endtime) > 0;
        }
        /// 
        /// 查询日志  并将数据分割成 多个集合
        /// 
        /// 
        /// 
        public List> Getlists(LogsQuery lq)
        {
            return LogsHelper.SpiltList(GetList(lq), 50);
        }

    }

最后在UI层设计数据库查询界面
日志可通过日期+类型查询
将查询出来的日志50条为一页进行切割并显示查询的总条数,总页数

 public partial class LogsForm : Form
    {
        public LogsForm()
        {
            InitializeComponent();
            Init();
        }
        public void Init()
        {
            this.Text = "";
            this.dgvLogs.ReadOnly = true;
            cbxType.DataSource = Enum.GetNames(typeof(LogsType));
            _pages = 0;
        }
        LogsBll bll = LogsBll.Create();
        List> list=new List>();
        private int _pages;
        private void RefreshTips()
        {
            this.lblCurrentPage.Text =String.Format("第{0}页",_pages);
            this.lblAllPage.Text = String.Format("共{0}页",list.Count);
            this.lblNum.Text= String.Format("共{0}条记录",50 * (list.Count - 1) + list[list.Count - 1].Count); 
        }
        private void btnQuert_Click(object sender, EventArgs e)
        {
            this.BeginInvoke(new Action(() =>
            {
                Cursor.Current = Cursors.WaitCursor;
                LogsQuery lq = new LogsQuery()
                {
                    starttime = dataTimeStart.Value,
                    endtime = dataTimeEnd.Value,
                    LType = (LogsType)Enum.Parse(typeof(LogsType), cbxType.Text)
                };
                list = bll.Getlists(lq);
                List list1 = list[0];
                if (list.Count > 0)
                {
                    dgvLogs.DataSource = list[0];
                    _pages = 1;
                    RefreshTips();
                }
            }));
            Cursor.Current= Cursors.Default;
        }

        private void btnHomePage_Click(object sender, EventArgs e)
        {
            this.BeginInvoke(new Action(() =>
            {
                if (list.Count > 0)
                {
                    dgvLogs.DataSource = list[0];
                    _pages = 1;
                    RefreshTips();
                }
                else
                {
                    return;
                }
            }));

        }

        private void btnEndPage_Click(object sender, EventArgs e)
        {
            this.BeginInvoke(new Action(() =>
            {
                if (list.Count > 0)
                {
                    dgvLogs.DataSource = list[list.Count - 1];
                    _pages = list.Count;
                    RefreshTips();
                }
                else
                {
                    return;
                }
            }));           
        }

        private void btnPreviousPage_Click(object sender, EventArgs e)
        {
            this.BeginInvoke(new Action(() =>
            {
                if (list.Count > 0)
                {
                    if(_pages > 1)
                    {
                        _pages--;
                        dgvLogs.DataSource = list[_pages-1];
                        RefreshTips();
                    }
                }
                else
                {
                    return;
                }
            }));
        }

        private void btnNextPage_Click(object sender, EventArgs e)
        {
            this.BeginInvoke(new Action(() =>
            {
                if (list.Count > 0)
                {
                    if (_pages < list.Count)
                    {
                        _pages++;
                        dgvLogs.DataSource = list[_pages-1];
                        RefreshTips();
                    }
                }
                else
                {
                    return;
                }
            }));
        }

    }

设计删除日志的UI

public partial class LogsSetingFrom : Form
    {
        public LogsSetingFrom()
        {
            InitializeComponent();
        }
        public void Init()
        {
            this.FormBorderStyle = FormBorderStyle.None;
            this.ControlBox = false;
            this.Text = "";
        }
        LogsBll bll = LogsBll.Create();
        private void btnDelect_Click(object sender, EventArgs e)
        {
            bll.EmptyTable();
            MessageBox.Show("删除成功");
        }

        private void btnDelectBetween_Click(object sender, EventArgs e)
        {
            bll.Delete(dtpStart.Value, dtpend.Value);
            MessageBox.Show("删除成功");
        }
    }

软件实时运行的日志界面
首先需要先建立一个队列用来存储日志内容,通过任务或者线程来对日志进行不断地写入,显示
到界面上
Bll层声名

    #region << 版 本 注 释 >>
    
    #endregion
    public class LogsQueue
    {
        /// 
        /// 日志队列    用于MainFrom中日志textbox控件展示日志使用
        /// 
        private static ConcurrentQueue RunningLogQueue = new ConcurrentQueue();

        /// 
        /// 向UI日志显示队列中添加一个对象
        /// 
        /// 
        public static void RunningLogQueue_AddOne(LogsInfo log)
        {
            log.LDataTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
            RunningLogQueue.Enqueue(log);
        }

        /// 
        /// 从UI日志队列中取出一个对象
        /// 
        /// 
        /// 
        public static bool RunningLogQueue_GetOne(out LogsInfo log)
        {
            return RunningLogQueue.TryDequeue(out log);
        }

        /// 
        /// 判断UI日志队列中是否有对象
        /// 
        /// 
        public static bool RunningLogQueue_HaveElement()
        {
            if (RunningLogQueue.Count <= 0)
            {
                return false;
            }
            else
            {
                return true;
            }
        }
    }

接着继续在Bll层声名任务,这里需要使用到Action事件,用来传递数据到UI层

    #region << 版 本 注 释 >>
    
    #endregion
    public class TaskLogs
    {
        LogsBll logbll;
        SystemSetBll ssbll;
        //定义事件
        public event Action SentLogsTxt;
        public TaskLogs()
        {
            logbll = LogsBll.Create();
            ssbll= SystemSetBll.Create();
            Task_UpdateRunningLog();
        }
        private CancellationTokenSource tskQueue1_cts = null;
        private void Task_UpdateRunningLog()
        {
            tskQueue1_cts = new CancellationTokenSource();
            Task task1 = new Task(() => { UpdateRunningLog(); }, tskQueue1_cts.Token, TaskCreationOptions.LongRunning);
            task1.Start();
        }
        private void UpdateRunningLog()
        {
            try
            {
                while (!tskQueue1_cts.IsCancellationRequested)
                {
                    if (LogsQueue.RunningLogQueue_HaveElement())
                    {
                        LogsInfo log = null;
                        if (LogsQueue.RunningLogQueue_GetOne(out log))
                        {
                            logbll.Add(log);//写入数据库
                            if (SentLogsTxt != null)
                            {
                                SentLogsTxt(log);//显示界面
                            }
                            SaveLog(log);
                        }
                    }
                    Thread.Sleep(10);
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        private void SaveLog(LogsInfo log)
        {
            try
            {
                string kk = ssbll.GetValue(PName.日志存放地址);
                if (!Directory.Exists(ssbll.GetValue(PName.日志存放地址)))
                { 
                    Directory.CreateDirectory(ssbll.GetValue(PName.日志存放地址));
                }
                string df = DateTime.Now.ToLongDateString();
                string addressErrorLog = ssbll.GetValue(PName.日志存放地址) + "\" + df + @"_other.txt";
                if (!File.Exists(addressErrorLog)) File.Create(addressErrorLog).Close();
                StringBuilder strBuilderErrorMessage = new StringBuilder();
                strBuilderErrorMessage.Append("日期:" + log.LDataTime + "rn");
                strBuilderErrorMessage.Append("标题:" + log.LTitle + "rn");
                strBuilderErrorMessage.Append("内容:"+log.LContent + "rn");
                strBuilderErrorMessage.Append("类型:" + log.LType.ToString() + "rn");
                strBuilderErrorMessage.Append("___________________________________________________rn");

                using (FileStream fs = new FileStream(addressErrorLog, FileMode.Append, FileAccess.Write))
                {
                    StreamWriter sw = new StreamWriter(fs, Encoding.Default);
                    sw.WriteLine(strBuilderErrorMessage);
                    sw.Close();
                    fs.Close();
                }
            }
            catch (Exception ex) {
                throw ex;
            }
        }
    }

最后设计软件运行得实时日志UI
这里使用委托来显示数据到界面上

public partial class LogsMainFrom : Form
    {
        public LogsMainFrom()
        {
            InitializeComponent();
            tlogs.SentLogsTxt += ShowLogs;          
        }
        TaskLogs tlogs=new TaskLogs();
        private void LogsMainFrom_Load(object sender, EventArgs e)
        {
            this.FormBorderStyle = FormBorderStyle.None;
            this.ControlBox = false;
            this.Text = "";
            this.tbxLogs.ReadOnly = true;
        }
        private void ShowLogs(LogsInfo logs)
        {
            Invoke(new Action(() =>
            {
                if (this.tbxLogs.Lines.Length > 1000) this.tbxLogs.Clear();//如果超过1000行,日志清零
                string msg = String.Concat(logs.LDataTime ,"  " ,logs.LTitle + "  " ,logs.LContent + "  " ,logs.LType.ToString() , "rn");
                this.tbxLogs.AppendText(msg);//显示日志到界面上
                this.tbxLogs.Select(this.tbxLogs.TextLength, 0);//光标定位到文本最后
            }));
        }
    }
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/881259.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号