Unity应用架构设计(13)——日志组件的实施

本文涉及的产品
日志服务 SLS,月写入数据量 50GB 1个月
简介:

对于应用程序而言,日志是非常重要的功能,通过日志,我们可以跟踪应用程序的数据状态,记录Crash的日志可以帮助我们分析应用程序崩溃的原因,我们甚至可以通过日志来进行性能的监控。总之,日志的好处很多,特别是对Release之后的线上版本进行异常的跟踪。

日志存储的分类

在平常开发时,我们通常喜欢在Debug模式下进行调试,通过断点,可以跟踪数据的变化。除了调试,另一种直观的方式是使用控制台输出,比如Java的system.out.println(),.NET的Console.WriteLine(),Swift的print()等等。在Untiy中,为我们提供了Debug.Log()方式来记录。

而对于线上的版本,上述两种调试都不行,那我们怎么来跟踪数据呢?

从日志的存储分类上来看,可以分为四类:控制台,文件系统,数据库,第三方平台

  • 控制台:本地开发时使用,记录数据和跟踪执行过程,方便直观
  • 文件系统:可以是一些用户行为性的日志,这些文件可以被用来监控执行时间,进行性能的分析,如果用户同意,则将这些日志传到服务器上
  • 数据库:记录了一些异常日志,也就是Catch了之后的行为,每次用户登录时,传到服务器,帮助分析原因
  • 第三方平台:比如友盟等,当应用闪退时,Crash原因会记录在友盟中,可以通过DashBoard查看

日志组件的设计

为了可以更加灵活的跟踪线上的变化,可以使用第三方的Analysis,也可以自建日志组件。我偏向于混合使用,所以接下来,谈谈一个日志组件的基本设计理念,如下图所示:

从上图可以看出,整个入口由工厂LogFactory来创建LogStrategy子类实例,LogStrategy是个抽象的模板类,定义了公共的处理方法,但并不知道怎样写日志(比如是写入到数据库呢还是到文件),写日志的行为交给子类去完成。

日志组件的实施

有了日志组件的设计图,接下来就是将理念落实到行动,让我们来实现它吧!

LogFactory是一个简单工厂,封装创建LogStrategy对象的代码。

public class LogFactory
{
    public static LogFactory Instance=new LogFactory();
    private LogFactory(){}
    private readonly Dictionary<string,LogStrategy> _strategies=new Dictionary<string, LogStrategy>()
    {
        {typeof(ConsoleLogStrategy).Name,new ConsoleLogStrategy() },
        {typeof(FileLogStrategy).Name,new FileLogStrategy() },
        {typeof(DatabaseLogStrategy).Name,new DatabaseLogStrategy() }
    }; 
    public LogStrategy Resolve<T>() where T:LogStrategy
    {
        return _strategies[typeof(T).Name];
    }
}
    

LogFactory内部定义了一个字典,Key为LogStrategy子类的类名,Value为具体的LogStrategy对象。通过一个公共接口Resolve<T>来获取相关对象。

使用字典比switch..case更直观,也更加容易扩展其他选项。更重要的是,不会对公共接口Resolve<T>进行修改。

LogStrategy是一个抽象类,即模板类。

它定义了一个公共的API,即Log。在方法Log中,定义了一些对内容的公共操作,因为对于日志来说,不管是记录在数据库还是文件系统,都将对内容拼接上设备类型、设备名称、操作系统、创建时间等基本信息。

同时还定义了一个抽象方法RecordMessage,对于需要写入的类型(文件系统Or数据库Or控制台)延迟到子类决定。

public abstract class LogStrategy
{
    private readonly StringBuilder _messageBuilder=new StringBuilder();
    protected IContentWriter Writer { get; set; }

    /// <summary>
    ///     模板方法
    /// </summary>
    protected abstract void RecordMessage(string message);

    protected abstract void SetContentWriter();

    /// <summary>
    ///     公共的API
    /// </summary>
    public void Log(string message,bool verbose=false)
    {
        if (verbose)
        {
            //公共方法
            RecordDateTime();
            RecordDeviceModel();
            RecordDeviceName();
            RecordOperatingSystem();
        }
        //抽象方法,交由子类实现
        RecordMessage(_messageBuilder.AppendLine(string.Format("Message:{0}", message)).ToString());
    }

    private void RecordDateTime()
    {
        _messageBuilder.AppendLine(string.Format("DateTime:{0}", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")));
    }

    private void RecordDeviceModel()
    {
        _messageBuilder.AppendLine(string.Format("Device Model:{0}",SystemInfo.deviceModel));
    }

    private void RecordDeviceName()
    {
        _messageBuilder.AppendLine(string.Format("Device Name:{0}", SystemInfo.deviceName));
    }

    private void RecordOperatingSystem()
    {
        _messageBuilder
            .AppendLine(string.Format("Operating System:{0}", SystemInfo.operatingSystem))
            .AppendLine();
    }

模板方法模式:在一个方法中定义算法的骨架,而将一些步骤延迟到子类。模板方法使得子类可以在不改变算法的结构下,重新定义算法中的某些步骤。

当在控制台Debug时,我们其实不需要设备类型,设备名称等信息,故公共接口Log提供了一个开关verbose来开启是否需要详细信息,默认为false,即关闭状态。

继承LogStrategy,创建自定义的日志策略

比如实现FileLogStrategy,除了override了 RecordMessage方法之外,还需要提供一个实现了IContentWriter接口的类,你可以直接在RecordMessage方法中写入日志,但可能有一些公共的操作,比如在异步线程,批量将10条数据写到文件或者数据库中,所以提供一个IContentWriter更加容易扩展。

public class FileLogStrategy:LogStrategy
{
    public FileLogStrategy()
    {
        SetContentWriter();
    }
    protected sealed override void SetContentWriter()
    {
        Writer = new FileContentWriter(); 
    }
    protected override void RecordMessage(string message)
    {
        Writer.Write(message);
    }

}

创建一个BaseContentWriter,提供了公共的写入方法,比如为了提高性能,文件的IO并不是马上写入文件,而是批量Flush。同样数据库记录日志也是一样,像Unit Of Work那样,批量向数据库写入数据,提高它的吞吐率。

根据需求使用不同的日志类

LogFactory.Instance.Resolve<FileLogStrategy>().Log("Welcome");

小结

不同于服务器端的日志组件,比如Log4J,只需要将日志写在本地文件系统中,客户端的日志相对来说复杂点,因为记录的日志是发生在用户的客户端,所以你必须要想办法把日志传到服务器,比如一些Crash的异常。既然要把日志发回来,在应用闪退时,必须能够持久化到本地,故我们会将日志写到文件系统或者数据库,然后在合适的时候将日志发送到服务器进行分析。当然,你也可以使用第三方的服务,比如友盟或者 Unity Analytics 来分析数据。
源代码托管在Github上,点击此了解

我的博客即将搬运同步至腾讯云+社区,邀请大家一同入驻:https://cloud.tencent.com/developer/support-plan

本博客为 木宛城主原创,基于 Creative Commons Attribution 2.5 China Mainland License发布,欢迎转载,演绎或用于商业目的,但是必须保留本文的署名 木宛城主(包含链接)。如您有任何疑问或者授权方面的协商,请给我留言。

本文转自木宛城主博客园博客,原文链接:http://www.cnblogs.com/OceanEyes/p/log_strategy.html,如需转载请自行联系原作者
相关实践学习
日志服务之使用Nginx模式采集日志
本文介绍如何通过日志服务控制台创建Nginx模式的Logtail配置快速采集Nginx日志并进行多维度分析。
目录
相关文章
|
1月前
|
运维 Cloud Native 持续交付
深入理解云原生架构及其在现代企业中的应用
随着数字化转型的浪潮席卷全球,企业正面临着前所未有的挑战与机遇。云计算技术的迅猛发展,特别是云原生架构的兴起,正在重塑企业的IT基础设施和软件开发模式。本文将深入探讨云原生的核心概念、关键技术以及如何在企业中实施云原生策略,以实现更高效的资源利用和更快的市场响应速度。通过分析云原生架构的优势和面临的挑战,我们将揭示它如何助力企业在激烈的市场竞争中保持领先地位。
|
6天前
|
存储 人工智能 JSON
RAG Logger:专为检索增强生成(RAG)应用设计的开源日志工具,支持查询跟踪、性能监控
RAG Logger 是一款专为检索增强生成(RAG)应用设计的开源日志工具,支持查询跟踪、检索结果记录、LLM 交互记录和性能监控等功能。
28 7
RAG Logger:专为检索增强生成(RAG)应用设计的开源日志工具,支持查询跟踪、性能监控
|
5天前
|
容灾 网络协议 数据库
云卓越架构:云上网络稳定性建设和应用稳定性治理最佳实践
本文介绍了云上网络稳定性体系建设的关键内容,包括面向失败的架构设计、可观测性与应急恢复、客户案例及阿里巴巴的核心电商架构演进。首先强调了网络稳定性的挑战及其应对策略,如责任共担模型和冗余设计。接着详细探讨了多可用区部署、弹性架构规划及跨地域容灾设计的最佳实践,特别是阿里云的产品和技术如何助力实现高可用性和快速故障恢复。最后通过具体案例展示了秒级故障转移的效果,以及同城多活架构下的实际应用。这些措施共同确保了业务在面对网络故障时的持续稳定运行。
|
1月前
|
运维 监控 Cloud Native
一行代码都不改,Golang 应用链路指标日志全知道
本文将通过阿里云开源的 Golang Agent,帮助用户实现“一行代码都不改”就能获取到应用产生的各种观测数据,同时提升运维团队和研发团队的幸福感。
|
1月前
|
存储 Prometheus 监控
Docker容器内进行应用调试与故障排除的方法与技巧,包括使用日志、进入容器检查、利用监控工具及检查配置等,旨在帮助用户有效应对应用部署中的挑战,确保应用稳定运行
本文深入探讨了在Docker容器内进行应用调试与故障排除的方法与技巧,包括使用日志、进入容器检查、利用监控工具及检查配置等,旨在帮助用户有效应对应用部署中的挑战,确保应用稳定运行。
49 5
|
2月前
|
Cloud Native 安全 持续交付
深入理解微服务架构及其在现代软件开发中的应用
深入理解微服务架构及其在现代软件开发中的应用
55 4
|
2月前
|
监控 持续交付 API
深入理解微服务架构及其在现代应用开发中的应用
深入理解微服务架构及其在现代应用开发中的应用
31 4
|
2月前
|
运维 Kubernetes Docker
深入理解容器化技术及其在微服务架构中的应用
深入理解容器化技术及其在微服务架构中的应用
68 1
|
1月前
|
弹性计算 API 持续交付
后端服务架构的微服务化转型
本文旨在探讨后端服务从单体架构向微服务架构转型的过程,分析微服务架构的优势和面临的挑战。文章首先介绍单体架构的局限性,然后详细阐述微服务架构的核心概念及其在现代软件开发中的应用。通过对比两种架构,指出微服务化转型的必要性和实施策略。最后,讨论了微服务架构实施过程中可能遇到的问题及解决方案。
|
2月前
|
Cloud Native Devops 云计算
云计算的未来:云原生架构与微服务的革命####
【10月更文挑战第21天】 随着企业数字化转型的加速,云原生技术正迅速成为IT行业的新宠。本文深入探讨了云原生架构的核心理念、关键技术如容器化和微服务的优势,以及如何通过这些技术实现高效、灵活且可扩展的现代应用开发。我们将揭示云原生如何重塑软件开发流程,提升业务敏捷性,并探索其对企业IT架构的深远影响。 ####
53 3
下一篇
开通oss服务