博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
使用MONO在MAC OS上开发——同步日志(一)
阅读量:4953 次
发布时间:2019-06-12

本文共 16939 字,大约阅读时间需要 56 分钟。

  原先打算再写点EXT.NET方面的,由于现在在玩Silverlight和Android,所以不打算写下去了。而且最近很忙,所以发帖也不会很及时。

  好了,转入正题了:最近客户有个需求,要求写个小程序监控生产线上的苹果一体机的日志文件并上传到服务器。开始想使用Perl或者Python,但是时间不够(因为对这两门语言还不太熟悉),于是想试试MONO。MONO虽然没想象中好用,但是还算勉强能用。

  虽然MonoDevelop还可以,但是还是比较喜欢使用VS开发。于是在VS里面先编码。值得注意的是:

  1. 如果是开发Winform程序,界面用GTK重画吧。
  2. 如果是在VS里面开发,最好将所有的编码和注释都用英文。否则换其他系统时,可能会出现乱码。
  3. 编写时需注意MONO是否支持,否则就是白写。

接下来,开始编码。

1.读取配置文件

  习惯用XML,发现不支持System.Xml.Linq,亦不支持System.Xml,读取ini文件也麻烦,于是干脆读取文本文件好了。示例配置如下:

MonitoringDirectoryType:['Immediate','Cycle']Path:['/Users/PRODUCTION/Public/FinalTest/LogsFolder','/Users/PRODUCTION/Public/FinalTest/LogsFolder']TargetPath:['/Volumes/mes_data/FINALTEST/n81a/{Y}/{M}/{D}/FIN012','/Volumes/mes_data/FINALTEST/n81a/{Y}/{M}/{D}/FIN012']IncludeSubdirectories:['FALSE','false']Filter:['*.TXT','*.CSV']BackupPath:['/Users/PRODUCTION/BACKUP/{Y}/{M}/{D}','/Users/PRODUCTION/BACKUP/{Y}/{M}/{D}']BackupExpired:['2','2']CycleMinutes:['','1440']

相关解析代码如下:

using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.IO;using MonitoringApp.Custom;using System.Text.RegularExpressions;using Gtk;namespace MonitoringApp.Code.App{    public class Configuration    {        private static bool isLoadFirst = false;        private static List
configLst; public static List
ConfigLst { get { if (configLst == null) { try { if (!isLoadFirst) return LoadFromInitParams(); else return null; } catch (Exception ex) { LogManager.WriteErrorLog(ex); return null; } } return configLst; } set { configLst = value; } } ///
/// Load Configuration file /// ///
private static List
LoadFromInitParams() { isLoadFirst = true; string _configPath = Path.Combine(Directory.GetCurrentDirectory(), "Configuration.txt"); if (File.Exists(_configPath)) { if (ConfigLst == null) ConfigLst = new List
(); else return ConfigLst; using (StreamReader sr = new StreamReader(_configPath)) { int lineIndex = 1; while (sr.Peek() > 0) { string str = sr.ReadLine().Trim(); if (str.Length == 0) continue; if (!str.Contains("[") || !str.Contains("]")) { LogManager.WriteErrorLog(string.Format("Config Error:'[' OR ']' Not Exist.At Line {0}.", lineIndex)); continue; } if (!str.Contains(":")) { LogManager.WriteErrorLog(string.Format("Config Error:':' Not Exist.At Line {0}.", lineIndex)); continue; } string[] names = str.Split(':'); str = str.Substring(str.IndexOf(':') + 1).Trim(']').Trim('[').Trim('\''); string[] strConfigs = str.Split(','); SetConfig(names, ConfigLst, strConfigs, lineIndex == 1); lineIndex++; } } return ConfigLst; } else { LogManager.WriteErrorLog(string.Format("can't find config file.Path:{0}.",_configPath)); return null; } } ///
/// Set Config /// ///
///
///
private static void SetConfig(string[] name, List
lst, string[] strConfigs, bool isLineOne) { try { var mcConfig = (MonitoringConfigurations)Enum.Parse(typeof(MonitoringConfigurations), name[0], true); //Set Values for (int i = 0; i < strConfigs.Length; i++) { string value = strConfigs[i].Trim('\''); switch (mcConfig) { case MonitoringConfigurations.MonitoringDirectoryType: { #region MonitoringDirectoryType Defalut:immediate switch (value.ToLower()) { case "immediate": { if (isLineOne) { MyConfig myConfig = new MyConfig(); myConfig.MDType = MonitoringDirectoryType.Immediate; lst.Add(myConfig); } else { lst[i].MDType = MonitoringDirectoryType.Immediate; } break; } case "cycle": { if (isLineOne) { MyConfig myConfig = new MyConfig(); myConfig.MDType = MonitoringDirectoryType.Cycle; lst.Add(myConfig); } else { lst[i].MDType = MonitoringDirectoryType.Cycle; } break; } default: { if (isLineOne) { MyConfig myConfig = new MyConfig(); myConfig.MDType = MonitoringDirectoryType.Immediate; lst.Add(myConfig); } else { lst[i].MDType = MonitoringDirectoryType.Immediate; } break; } } #endregion break; } case MonitoringConfigurations.Path: #region Path if (isLineOne) { MyConfig myConfig = new MyConfig(); myConfig.Path = value; lst.Add(myConfig); } else { lst[i].Path = value; } #endregion break; case MonitoringConfigurations.IncludeSubdirectories: #region IncludeSubdirectories if (isLineOne) { MyConfig myConfig = new MyConfig(); myConfig.IncludeSubdirectories = Convert.ToBoolean(value); lst.Add(myConfig); } else { lst[i].IncludeSubdirectories = Convert.ToBoolean(value); } #endregion break; case MonitoringConfigurations.Filter: #region Filter if (isLineOne) { MyConfig myConfig = new MyConfig(); myConfig.Filter = value; lst.Add(myConfig); } else { lst[i].Filter = value; } break; #endregion case MonitoringConfigurations.BackupPath: #region BackupPath if (isLineOne) { MyConfig myConfig = new MyConfig(); myConfig.BackupPath = value; lst.Add(myConfig); } else { lst[i].BackupPath = value; } #endregion break; case MonitoringConfigurations.TargetPath: #region TargetPath if (isLineOne) { MyConfig myConfig = new MyConfig(); myConfig.TargetPath = value; lst.Add(myConfig); } else { lst[i].TargetPath = value; } #endregion break; case MonitoringConfigurations.BackupExpired: #region BackupExpired Unit:days Default:30 if (isLineOne) { MyConfig myConfig = new MyConfig(); myConfig.BackupExpired = Convert.ToInt32(value.Length == 0 ? "30" : value); lst.Add(myConfig); } else { lst[i].BackupExpired = Convert.ToInt32(value.Length == 0 ? "30" : value); } #endregion break; case MonitoringConfigurations.CycleMinutes: #region CycleMinutes Unit:Minute Default:60 if (isLineOne) { MyConfig myConfig = new MyConfig(); myConfig.CycleMinutes = Convert.ToInt32(value.Length == 0 ? "60" : value); lst.Add(myConfig); } else { lst[i].CycleMinutes = Convert.ToInt32(value.Length == 0 ? "60" : value); } #endregion break; default: break; } } } catch (Exception ex) { LogManager.WriteErrorLog(ex); } } }}

 

 

值得注意的是:

  1. 这里是按行读取的。从读取配置来看,可以看出,是支持多个配置项的。
  2. 如果出错,会记录日志。
  3. 和客户讲解如何配置是一件麻烦的事情。相关配置解释如下:
MonitoringDirectoryType:目录类型,仅支持两个值(Immediate、Cycle)。Immediate表示即时监控(默认值),Cycle表示周期监控。		Path:监控目录路径。必须是存在的路径。	TargetPath:目标目录路径。可以是远程目录路径。不能使用SMB路径,而应该是用如“/Volumes/mes_data/n81a”的类型。	IncludeSubdirectories:是否涵盖子目录。	Filter:过滤字符串。如“*”表示监控所有文件,“*.txt”表示监控所有的文本文件。	BackupPath:备份路径。	BackupExpired:备份过期时间。单位是天。必须为整数。默认值30天。	CycleMinutes:周期循环时间。单位是分。 必须为整数。默认值60分钟。

 

然后针对配置写个说明文档,这样客户就会配置了。

2)记录日志

程序运行起来总不可避免的会遇到各种问题,记录日志就不可避免了。相关代码如下:

using System;using System.Collections.Generic;using System.IO;using System.Linq;using System.Text;using Gtk;namespace MonitoringApp.Code.App{    public class LogManager    {        public static object obj = new object();        static LogManager()        {        }        #region Fields and Properties        private static string _logPath = string.Empty;        public static string LogPath        {            get            {                lock (obj)                {                    if (_logPath == string.Empty)                    {                        var _logStr = string.Format("{0}/log/{1}/{2}", Path.Combine(Directory.GetCurrentDirectory(), "Data"), DateTime.Now.ToString("yyyy-MM"), DateTime.Now.Day);                        if (!System.IO.Directory.Exists(_logStr))                            System.IO.Directory.CreateDirectory(_logStr);                        return string.Format("{0}/", _logStr);                    }                    return _logPath;                }            }            set { _logPath = value; }        }        private static string _logFielPrefix = string.Empty;        public static string LogFielPrefix        {            get { return _logFielPrefix; }            set { _logFielPrefix = value; }        }        #endregion        #region Log        public static void WriteLog(string logFile, string msg)        {            try            {                lock (obj)                {                    var _sb = new System.Text.StringBuilder();                    _sb.Append(LogPath).Append(LogFielPrefix).Append(logFile).Append(".Log");                    using (var _sw = System.IO.File.AppendText(_sb.ToString()))                    {                        _sw.WriteLine("==============================={0}===============================", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));                        _sw.WriteLine(msg);                        _sw.Flush();                        _sw.Close();                        Console.WriteLine(msg);                    }                }            }            catch            { }        }        public static void WriteLog(LogFile logFile, string msg)        {            WriteLog(logFile.ToString(), msg);        }        public static void WriteTraceLog(string msg)        {            Console.WriteLine(msg);        }        public static void WriteErrorLog(string msg)        {            WriteLog(LogFile.Error, msg);        }        public static void WriteErrorLog(Exception ex)        {            var _sbError = new StringBuilder();            _sbError.Append("[Message]").Append(ex.Message);            _sbError.Append("\r\n[TargetSite]").Append(ex.TargetSite);            _sbError.Append("\r\n[StackTrace]").Append(ex.StackTrace);            _sbError.Append("\r\n[Source]").Append(ex.Source);            foreach (var _item in ex.Data.Keys)            {                _sbError.Append("\r\n[").Append(_item).Append("]").Append(ex.Data[_item]);            }            if (ex.InnerException != null && ex.InnerException.Message != ex.Message)            {                _sbError.AppendLine("____________________________________________________________________________________");                _sbError.Append("[Message]").Append(ex.InnerException.Message);                _sbError.Append("\r\n[TargetSite]").Append(ex.InnerException.TargetSite);                _sbError.Append("\r\n[StackTrace]").Append(ex.InnerException.StackTrace);                _sbError.Append("\r\n[Source]").Append(ex.InnerException.Source);                _sbError.AppendLine("____________________________________________________________________________________");            }            WriteLog(LogFile.Error, _sbError.ToString());        }        public static void WriteWarningLog(string msg)        {            WriteLog(LogFile.Warning, msg);        }        #endregion    }    public enum LogFile    {        Trace,        Warning,        Error,        SQL,        System    }}

值得注意的是“Directory.GetCurrentDirectory()可以获取到当前用户的个人目录,至于获取到程序当前目录路径,Winform的那一套不管用(如果哪位朋友找到了适合的方法,请留言)。苹果系统和Window系统差别太大,从没玩过苹果系统,刚开始玩还挺不习惯的。

接下来,讲述如何监控目录以及定时备份,最后讲述如何发布部署。发布部署才是最重要的一环。不上生产线,就不知道会有什么问题。当初以为这个小程序,一天就能搞定,结果中秋3天都废了。还好万幸搞定。时间关系,就此打住。

转载于:https://www.cnblogs.com/codelove/archive/2011/09/26/2192366.html

你可能感兴趣的文章
通过用户模型,对数据库进行增删改查操作。
查看>>
去除数组中重复的元素
查看>>
Nginx配置文件nginx.conf中文详解(转)
查看>>
POJ 1988 Cube Stacking
查看>>
POJ 1308 Is It A Tree?(并查集)
查看>>
N进制到M进制的转换问题
查看>>
Android------三种监听OnTouchListener、OnLongClickListener同时实现即其中返回值true或者false的含义...
查看>>
MATLAB实现多元线性回归预测
查看>>
Mac xcode 配置OpenGL
查看>>
利用sed把一行的文本文件改成每句一行
查看>>
使用Asyncio的Coroutine来实现一个有限状态机
查看>>
Android应用开发:核心技术解析与最佳实践pdf
查看>>
python——爬虫
查看>>
2.2 标识符
查看>>
孤荷凌寒自学python第五天初识python的列表
查看>>
孤荷凌寒自学python第五十八天成功使用python来连接上远端MongoDb数据库
查看>>
求一个字符串中最长回文子串的长度(承接上一个题目)
查看>>
简单权限管理系统原理浅析
查看>>
springIOC第一个课堂案例的实现
查看>>
求输入成绩的平均分
查看>>