基于rabbitmq的日志系统(.NET和java)

本文介绍了在MES业务环境下,如何利用Java和.NET构建基于RabbitMQ的日志系统。系统采用WebAPI、log4和RabbitMQ,通过MQProxy和MQHandler进行日志数据的传输和处理,LogHandler作为独立服务从RabbitMQ获取数据并用log4写入txt文件。在Java客户端,也使用RabbitMQ进行日志记录。
摘要由CSDN通过智能技术生成

基于rabbitmq的日志系统(.NET和java)


很多年不写博客了,希望写一些东西总结总结。
我从2011年开始做工业软件生产执行系统架构,2016年对整体架构进行重新规划和重构。

我们MES架构中关于日志模块的设计思路,接下来我会介绍在MES业务下Java和MongoDB的一些思路总结

架构采用WebAPI,日志采用log4,中间用RabbitMQ进行分流,架构图如下:
这里写图片描述
框架采用MEF+Autofac的IOC框架,每个二次开发部分采用插件形式进行扩展开发,需要进行日志的项目统一引用MQProxy代理项目,通过代理项目采用WCF方式传输到MQHandler项目(127.0.0.1:9005),然后MQHandler调用各自方法(操作日志、异常日志、其它)放到RabbitMQ服务中;然后独立一个LogHandler服务(日志处理项目Windows服务)定时从RabbitMQ服务获取数据分量调用log4开源框架写入到txt文件中。
框架由于大数据的原因,覆写Java客户端,也往RabbitMQ服务写入消息,同样用上面的LogHandler服务进行日志的写入。


调用MQProxy项目,一句话输出日志:

//错误日志调用如下:
ClientMQProxy.Instance().SendErrorLog("Department/QueryMenu:" + ex.Message.ToString(), new StackTrace(new StackFrame(true)));

//异常日志调用如下:
ClientMQProxy.Instance().SendInfoLog("Department/QueryMenu:");

IPlugin接口


MQProxy项目

internal interface IClientMQProxy
{
	/// <summary>
    /// 同步发送错误日志数据信息
    /// </summary>
    /// <param name="strlogDataTransmissionObj">传输日志内容对象</param>
    /// <param name="stackTrace">堆栈跟踪对象</param>
    void SendErrorLog(string strlogDataTransmissionObj, StackTrace stackTrace);

    /// <summary>
    /// 同步发送错误日志数据信息
    /// </summary>
    /// <param name="strlogDataTransmissionObj">传输日志内容对象</param>
    void SendErrorLog(string strlogDataTransmissionObj);

    /// <summary>
    /// 同步发送操作日志数据信息
    /// </summary>
    /// <param name="strInfoDataTransmissionObj">传输操作日志内容对象</param>
    void SendInfoLog(string strInfoDataTransmissionObj);
}

public class ClientMQProxy : IClientMQProxy
{
	/// <summary>
    /// Http绑定元素
    /// </summary>
    static BasicHttpBinding HttpBind { get; set; }

    /// <summary>
    /// “日志数据消息”契约接口抽象对象
    /// </summary>
    IPlugin.IMQProxy iMQProxy;

    /// <summary>
    /// 静态实例对象
    /// </summary>
    static ClientMQProxy instace = null;

    /// <summary>
    /// 锁
    /// </summary>
    static readonly object padlock = new object();

    /// <summary>
    /// 静态实例方法(返回静态字段)
    /// </summary>
    public static ClientMQProxy Instance()
    {
		lock (padlock)
		{
		    if (instace == null)
            {
	            instace = new ClientMQProxy();
                HttpBind = MQProxyTransferConfig.BasicHttpBinding_Text(HttpBind, new XmlDictionaryReaderQuotas());
                instace.RunService("http://127.0.0.1:9005");
            }
            return instace;
        }
    }

    /// <summary>
    /// 根据“服务类型”来进行服务的启动
    /// </summary>
    /// <param name="strEndpointAddress">需要连入的日志服务地址</param>
    void RunService(string strEndpointAddress)
    {
	    try
        {
	        //增加服务的同时,添加到字典里
            iMQProxy = DataBind(HttpBind, strEndpointAddress);
	    }
        catch{ }
    }

    /// <summary>
    /// 客户端发送错误日志调用方法
    /// </summary>
    /// <param name="strInfoDataTransmissionObj"></param>
    public void SendInfoLog(string strInfoDataTransmissionObj)
    {
	    if (string.IsNullOrWhiteSpace(strInfoDataTransmissionObj))
	        return;

		StringBuilder sb = new StringBuilder();
		sb.Append(strInfoDataTransmissionObj);

		string strErrorMsg = "";
		try
		{
			//申明传输消息体对象
            MsgDataTransmissionObj dto = new MsgDataTransmissionObj();
            //序列化发送到服务端
            MemoryStream memStream = Serialize(sb.ToString(), out strErrorMsg);
            dto.DataContent = memStream;
            if (iMQProxy != null)//发送消息体
				iMQProxy.SendInfoMessage(dto);
		}
		catch (Exception ex)
		{
			string strTempStackTrace = "";
			if (ex.StackTrace != null)
				strTempStackTrace = "\r\n错误点:" + ex.StackTrace.ToString() + strErrorMsg;
		}
	}

	/// <summary>
    /// 客户端发送错误日志调用方法
    /// </summary>
    /// <param name="strLogDataTransmissionObj">日志数据传输对象</param>
    /// <param name="stackTrace">堆栈跟踪对象,调用示例: new StackTrace(new StackFrame(true))</param>
    public void SendErrorLog(string strLogDataTransmissionObj, StackTrace stackTrace)
	{
		StringBuilder sb = new StringBuilder();

		if (stackTrace != null && stackTrace.FrameCount > 0)
		{
			StackFrame sf = stackTrace.GetFrame(0);
			string strTraceFileName = sf.GetFileName();//获取包含所执行代码的文件名
			string strTraceMethodName = sf.GetMethod().Name;//获取出错的方法名
			string strTraceCodeLineNum = sf.GetFileLineNumber().ToString();//获取出错的代码的行号
			string strTraceCodeColNum = sf.GetFileColumnNumber().ToString();//获取出错的代码的列号

            //拼接堆栈跟踪信息
            sb.Append("Trace DateTime:");
            sb.Append(DateTime.Now.Year.ToString() + "-" +
                DateTime.Now.Month.ToString("00") + "-" +
                DateTime.Now.Day.ToString("00") + " " +
                DateTime.Now.Hour.ToString("00") + ":" +
                DateTime.Now.Minute.ToString("00") + ":" +
                DateTime.Now.Second.ToString("00") + "\r\n");
            sb.Append("Trace File Name:" + strTraceFileName + "\r\n");
            sb.Append("Trace Method Name:" + strTraceMethodName + "\r\n");
            sb.Append("Trace Code Line Num:" + strTraceCodeLineNum + "\r\n");
            sb.Append("Trace Code Column Num:" + strTraceCodeColNum + "\r\n");
		}
		sb.Append("Trace Log Message:" + strLogDataTransmissionObj + "\r\n");

		string strErrorMsg = "";
		try
		{
			//申明传输消息体对象
			MsgDataTransmissionObj dto = new MsgDataTransmissionObj();

            //序列化发送到服务端
            MemoryStream memStream = Serialize(sb.ToString(), out strErrorMsg);

            dto.DataContent = memStream;

            if (iMQProxy != null)//发送消息体
	            iMQProxy.SendErrorMessage(dto);
		}
        catch (Exception ex)
        {
			string strTempStackTrace = "";

			if (ex.StackTrace != null)
				strTempStackTrace = "\r\n错误点:" + ex.StackTrace.ToString() + strErrorMsg;
		}
	}

    /// <summary>
    /// 客户端发送错误日志调用方法
    /// </summary>
    /// <param name="strLogDataTransmissionObj">日志数据传输对象</param>
    public void SendErrorLog(string strLogDataTransmissionObj)
    {
		if (string.IsNullOrWhiteSpace(strLogDataTransmissionObj))
			return;

		string strErrorMsg = "";
		try
		{
			//申明传输消息体对象
			MsgDataTransmissionObj dto = new MsgDataTransmissionObj();

			//序列化发送到服务端
			MemoryStream memStream = Serialize(strLogDataTransmissionObj, out strErrorMsg);

			dto.DataContent = memStream;

			if (iMQProxy != null)//发送消息体
				iMQProxy.SendErrorMessage(dto);
		}
        catch (Exception ex)
        {
	        string strTempStackTrace = "";

            if (ex.StackTrace != null)
	            strTempStackTrace = "\r\n错误点:" + ex.StackTrace.ToString() + strErrorMsg;
		}
	}

    /// <summary>
    /// “数据消息”绑定
    /// </summary>
    /// <param name="binding">绑定元素对象</param>
    /// <param name="str_EndpointAddress">端节点地址</param>
    /// <returns></returns>
    IMQProxy DataBind(System.ServiceModel.Channels.Binding binding, string str_EndpointAddress)
    {
		//创建通道
        ChannelFactory<IPlugin.IMQProxy> channelFactory = new ChannelFactory<IPlugin.IMQProxy>(binding, str_EndpointAddress);
        IPlugin.IMQProxy iDataContract = channelFactory.CreateChannel();

        channelFactory.Closing += new EventHandler(channelFactory_Closing);
        channelFactory.Faulted += new EventHandler(channelFactory_Faulted);

        return iDataContract;
	}
}

MQHandler项目

//日志Host启动WCF服务类
internal sealed class RunSelfHostLog
{
    /// <summary>
    /// 端节点地址
    /// </summary>
    string strBaseAddress { get; set; }

    /// <summary>
    /// 启动Windows服务名称
    /// </summary>
    string strSrvName { get; set; }

    /// <summary>
    /// 构造
    /// </summary>
    /// <param name="strBaseAddress">地址</param>
    /// <param name="strSrvName">服务名称</param>
    public RunSelfHostLog(string strBaseAddress, string strSrvName)
    {
        this.strBaseAddress = strBaseAddress;
        this.strSrvName = strSrvName;
    }

    /// <summary>
    /// 创建服务,并打开
    /// </summary>
    /// <param name="strErrorMsg">错误消息</param>
    internal bool Run(out string strErrorMsg)
    {
        strErrorMsg = "";

        //需要创建的承载日志的wcf服务类型
        Type type = typeof(MQService);

        //绑定元素对象
        Binding binding = new BasicHttpBinding();

        //终结点实现的协议
        Type objContract = typeof(IPlugin.IMQProxy);

        try
        {
            Uri uri = new Uri(strBaseAddress);
        }
        catch
        {
            strErrorMsg = "创建【" + strSrvName + "】服务指定的地址:【" + strBaseAddress + "】有错误";

            //调用消息框架发送日志
            MQBase mqBase = new MQBase();
            mqBase.SendErrorLogMessage(strErrorMsg);

            return false;
        }

        try
        {
            ServiceHost serviceHost = new ServiceHost(type);

            BasicHttpBinding httpBind = (BasicHttpBinding)binding;                
            httpBind = MQProxyTransferConfig.BasicHttpBinding_Text(httpBind, new XmlDictionaryReaderQuotas());
            serviceHost.AddServiceEndpoint(objContract, httpBind, strBaseAddress);

            serviceHost.Open();

            return true;
        }
        catch (Exception ee)
        {
            //调
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值