【代码篇】从零开始一步步搭建自己的golang框架(三)

上一篇文章里,我们定了项目基本目录结构。现在来回顾一下我的思路:

  1. 创建入口文件;
  2. 指定配置、日志目录;
  3. 指定数据库、队列、缓存组件目录;
  4. 创建数据处理的controller目录;
  5. 指定公共函数等杂项。

接下来,我们还是按照这个顺序填充代码。

入口文件

func main()  {
    config.InitConfig()
    logger.InitLogger()
}

暂且忽略一些实现细节,我们需要先初始化配置和日志,先来看看日志,我选用Uber的zap日志库。来看看日志模块怎么写?

日志

package logger

import (
    "go.uber.org/zap"
    "go.uber.org/zap/zapcore"
    "gopkg.in/natefinch/lumberjack.v2"
)

var l *zap.Logger

func InitLogger(logPath, logLevel string) error {
    hook := lumberjack.Logger{
        Filename:   logPath,
        MaxSize:    1024,
        MaxBackups: 3,
        MaxAge:     7,
        Compress:   true,
    }
    w := zapcore.AddSync(&hook)

    var level zapcore.Level
    switch logLevel {
    case "debug":
        level = zap.DebugLevel
    case "info":
        level = zap.InfoLevel
    case "error":
        level = zap.ErrorLevel
    default:
        level = zap.DebugLevel
    }

    encoderConfig := zap.NewProductionEncoderConfig()
    encoderConfig.EncodeTime = zapcore.ISO8601TimeEncoder
    core := zapcore.NewCore(
        zapcore.NewConsoleEncoder(encoderConfig),
        w,
        level,
    )

    l = zap.New(core)

    return nil
}

func GetLogger() *zap.Logger {
    return l
}

我们先定义一个包级的全局变量l,类型是*zap.Logger,并创建了InitLogger和GetLogger这两个函数。因为,zap不支持日志归档,所以在InitLogger中定义了一个lumberjack的hook,用来归档日志。我们可以看到InitLogger这个方法有两个入参:logPath和logLevel。一般来讲,这些参数应该是放在配置文件里的,接下来我们来写配置。

配置

我们简单地创建一个config.json文件来存放配置:
config.json:

{
  "log_config": {
    "log_path": "{your_path}",
    "log_level": "debug"
  }
}

然后在config.go中创建相应的结构体,之后定义InitConfig和GetConfig方法,在InitConfig方法中,我读取了配置文件的内容,然后解析到结构体中,并处理了错误,如果有错误信息的话,我会将错误信息包裹一层,方便以后的错误定位。InitConfig有一个入参,就是配置文件的路径,这个参数我会从命令行中获取。
config.go:

package config

import (
    "encoding/json"
    "github.com/pkg/errors"
    "io/ioutil"
)

type LogConfig struct {
    LogPath string `json:"log_path"`
    LogLevel string `json:"log_level"`
}

type Config struct {
    LogConfig LogConfig `json:"log_config"`
} 

var conf Config

func InitConfig(configPath string) error {
    configFile, err := ioutil.ReadFile(configPath)
    if err != nil {
        err = errors.Wrap(err, "Read config file failed.")
        return err
    }
    err = json.Unmarshal(configFile, &conf)
    if err != nil {
        err = errors.Wrap(err, "Unmarshal config file failed.")
        return err
    }
    return nil
}

func GetConfig() Config {
    return conf
}

我们当然不止这么一点配置,我们还有数据库、缓存等配置没有添加,但不急,我们先理出一个路线,之后的配置可以依葫芦画瓢。

调整入口文件

好,日志和配置的初始化大致写好了,我们回过头来看一下入口文件的调整:

package main

import (
    "flag"
    "fmt"
    "github.com/TomatoMr/awesomeframework/config"
    "github.com/TomatoMr/awesomeframework/logger"
    "os"
)

func main()  {
    var configPath string
    flag.StringVar(&configPath, "config", "", "配置文件路径")
    flag.Parse()

    if configPath == "" {
        fmt.Printf("Config Path must be assigned.")
        os.Exit(1)
    }

    var err error
    err = config.InitConfig(configPath)
    if err != nil {
        fmt.Printf("Init config failed. Error is %v", err)
        os.Exit(1)
    }

    logConfig := config.GetConfig().LogConfig

    err = logger.InitLogger(logConfig.LogPath, logConfig.LogLevel)
    if err != nil {
        fmt.Printf("Init logger failed. Error is %v", err)
        os.Exit(1)
    }

    logger.GetLogger().Info("Init success.")
}

我们调整了入口文件,从命令行里获取配置文件路径,之后初始化了配置和日志,最后打印初始化结果。

测试一下

首先,编译一下:

$ go build 

接着修改一下你的config.json文件的log_path,然后在命令行指定一下你的配置文件路径:

$ awesomeframework --config={$your_path}/config.json

最后,来看一下运行正不正常,日志文件的打印如下:

2020-01-19T20:41:57.506+0800    info    Init success.

小结

到目前为止,我们初始化了配置和日志,接下去要开始初始化数据库等组件。可以在https://github.com/TomatoMr/awesomeframework
找到今天的代码。未完待续……



欢迎关注我的公众号:onepunchgo。

原文地址:https://blog.51cto.com/14664952/2467955

时间: 2024-10-02 11:05:51

【代码篇】从零开始一步步搭建自己的golang框架(三)的相关文章

【代码篇】从零开始一步步搭建自己的golang框架

前言 import cycle not allowed 不知道是不是有很多学习golang的新人会遇到这样的问题.包循环引用这个问题,让人很头疼,尤其是在项目越来越复杂的时候,出现这么一句报错,这意味着你可能需要修改很多代码,这对一个新人来讲压力很大.通常来讲,解决这个错误的办法是将需要引用的那个包抽象成接口,解耦后调用.但这不是我这个篇章想要讲的内容.这个系列主要讲的是如何从代码组织架构方面去避免这个问题.从零开始一步步搭建自己的golang框架.这个篇章将实现以下的功能: 一个通用的基础框架

【代码篇】从零开始一步步搭建自己的golang框架(四)

上篇文章讲到配置和日志已经初始化了,这篇文章接着把数据库和redis初始化完成. 初始化数据库 数据库orm我选用xorm.首先在config.json和config.go添加对应的数据库配置.config.json: "db_config": { "db_host": "127.0.0.1", "db_port": "3306", "db_user": "root"

【代码篇】从零开始一步步搭建自己的golang框架(七)

这个框架的目标是作为一个通用的框架,我希望它大而全,在日后可以直接作为我其他项目的基础模板,所以我还想继续给他添加一些功能,就当写一些demo进去吧.这篇文章,我将会添加一个队列的功能. nsq 队列有很多种,我选择nsq.使用nsq需要知道以下几个概念: nsqd:负责维护队列的组件,接受消息排队和投递: nsqlookupd:管理nsq集群的组件: nsqadmin:nsq的web管理组件: topic:消息的集合.产生消息,需要指定该消息属于哪个topic的: channel:队列消息的副

【代码篇】从零开始一步步搭建自己的golang框架(六)

基本上这个基础框架拿到手之后就可以做一些自己想要做的改动了,比如你想添加个队列的插件,你可以在相应的目录里面进行修改了,但我想让它更通用一些,本篇文章将会启动一个websocket服务,并且把配置文件改成yaml格式. 修改配置 之所以想要把配置从json改为yaml,有以下几点原因: json主要是用于信息传输,而yaml更适合作为配置文件的格式来使用,两者的用途不一样: yaml格式看起来比json更加清晰: 在yaml文件中可以添加注释,让配置更加易懂. 在此,解析yaml文件用的包是"g

从零开始实现一个简易的Java MVC框架(三)--实现IOC

Spring中的IOC IoC全称是Inversion of Control,就是控制反转,他其实不是spring独有的特性或者说也不是java的特性,他是一种设计思想.而DI(Dependency Injection),即依赖注入就是Ioc的一种实现方式.关于Ioc和DI的具体定义和优缺点等大家可以自行查找资料了解一下,这里就不详细赘述,总之spring的IoC功能很大程度上便捷了我们的开发工作. 在实现我们的Ioc之前,我们先了解一下spring的依赖注入,在spring中依赖注入有三种方式

不使用 vue-cli 与 vue 模版,使用 Vue2.x + webpack4.x 从零开始一步步搭建项目框架

说明 这是我根据慕课网上的一个课程 Vue+Webpack打造todo应用 过程一步步搭下来的框架,去掉了业务相关的逻辑. 项目最终的效果包括了引入vue框架:使用CSS预处理器:使用babel:引用图片等静态资源:区分开发环境与生成环境,并做相应优化等.基本接近真正做项目时候的配置. 但是!! 毕竟是我个人根据练习课程搭的框架,跟真实工作可能有区别,请谨慎直接用于工作环境!!! 项目的最终成果看这里:https://gitee.com/Dandelion_/vue-webpack-scaffo

一步步搭建 Spring Boot maven 框架的工程

摘要:让Spring应用从配置到运行更加快速,演示DIY Spring Boot 框架时,如何配置端口号,如何添加日志. Spring Boot 框架帮助开发者更容易地创建基于Spring的应用程序和服务,使得开发者能够快速地获得所需要的Spring功能. 提供了非功能性的大型项目类特性,如(如内嵌服务器.安全.度量.健康检查.外部化配置),内部封装了tomcat的一些核心jar包,将发布封装了,因此不需要将项目(war包)发布到外部tomcat上. 搭建一个简单的.基于Restfull 风格的

一步步搭建自己的博客 .NET版(3、注册登录功能)

前言 这次开发的博客主要功能或特点:    第一:可以兼容各终端,特别是手机端.    第二:到时会用到大量html5,炫啊.    第三:导入博客园的精华文章,并做分类.(不要封我)    第四:做个插件,任何网站上的技术文章都可以转发收藏 到本博客. 所以打算写个系类:<一步步搭建自己的博客> 一.一步步搭建自己的博客  .NET版(1.页面布局.blog迁移.数据加载) 二.一步步搭建自己的博客  .NET版(2.评论功能) 三.一步步搭建自己的博客  .NET版(3.注册登录功能) 四

一步步搭建物联网系统——GNU/Linux 强大且Free

GNU/Linux 强大且Free 什么是Linux Linux是一种自由和开放源码的类UNIX操作系统内核.目前存在着许多不同的Linux发行版,可安装在各种各样的电脑硬件设备,从手机.平 板电脑.路由器和影音游戏控制台,到桌上型电脑,大型电脑和超级电脑.Linux是一个领先的操作系统内核,世界上运算最快的10台超级电脑运行的都是基 于Linux内核的操作系统. Linux操作系统也是自由软件和开放源代码发展中最著名的例子.只要遵循GNU通用公共许可证,任何人和机构都可以自由地使用Linux的