手把手教你完成MaxCompute JDBC自定义日志配置

注:MaxCompute原名ODPS,是阿里云自研的大数据计算平台,文中出现的MaxCompute与ODPS都指代同一平台,不做区分

与MaxCompute JDBC相关的日志有两种,一种是由JDBC内部代码直接输出的日志,第二种是JDBC抛出异常后,由调用JDBC API的宿主应用捕获后输出的。由于第二类日志取决于宿主应用如何处理异常及如何配置日志体系,所以本文主要讨论的对象是第一种日志。

在2.0-beta之前,MaxCompute JDBC的日志只会输出到命令行终端(标准输出流),它底层使用的是JDK自带的 java.util.logging 的 ConsoleHandler。所以除非你是在命令行启动宿主应用的(相对的另一种方式是在可视化界面里双击可执行文件来启动宿主应用,并没有控制台界面),不然日志信息并不好找。这就给用户诊断问题和排查错误带来了不便。

为了让用户能自定义日志的相关配置,比如让用户自己来决定日志输出到终端还是文件、输出的日志文件应该放在哪里,又或者输出的日志文件如何做rotation等。MaxCompute JDBC 在 2.0-beta 中引入了slf4jlogback来让用户能自定义日志配置。为了避免JDBC选择的 slf4j 日志实现框架与宿主应用的 slf4j 日志实现框架产生冲突,MaxCompute JDBC的JAR包中并没有包含某个特定 slf4j 实现的JAR包。而与 logback 之间也不是强依赖的,只有当宿主应用不包含任何 slf4j 日志实现的时候,用户可以通过在classpath中加入 logback 的JAR包,并向JDBC传入logback的配置文件来启用该实现。

  • 为什么slf4j日志实现框架之间会产生冲突?

slf4j 是为了统一不同日志框架的行为和API而产生的一套日志门面框架,它只提供API,但并不提供具体的日志解决方案实现。所以通常需要配合另一种具体的日志实现框架一起使用,比如 logbacklog4j 。而假设MaxCompute JDBC选择的是 slf4j + logback ,而宿主应用选择的是 slf4j + log4j ,那么运行时就会出现冲突。因为通常用户在编程时会调用 slf4jLoggerFactory.getLogger来获取日志实例,而在该方法首次被调用时会绑定一个具体的 slf4j 的实现,该行为依赖一个叫做org.slf4j.impl.StaticLoggerBinder的类。而该类在所有 slf4j 的日志实现框架中都会存在,所以当多套 slf4j 日志实现同时存在于classpath的时候,完全依赖于运行时classloader先加载了哪套实现的org.slf4j.impl.StaticLoggerBinder,加载了谁就使用谁的实现以及配置,而这是带有不确定性的,这也是常见的一种JAR包冲突问题。所以如果MaxCompute JDBC带入了与宿主应用不同的 slf4j 日志实现,那么可能会造成宿主应用在运行时获取到另一套实现的日志实例,从而让宿主应用原有的日志配置失效。

据不完全归纳,我暂且将MaxCompute JDBC的用户大致分为两类,分别是取数者和开发者。

  • 取数者
    这类用户通常是某类数据查询或分析工具的使用者,他们需要在取数工具中添加MaxCompute的JDBC Driver,然后配置jdbc url等若干参数,从而利用该工具完成对MaxCompute的SQL查询。
  • 开发者
    这类用户通常是数据产品的开发者,他们通过调用SDK或JDBC的API来编写查询逻辑的相关代码,从而开发出适合目标用户使用的软件产品。

那么现在我将针对这两类用户分别讲讲如何完成自定义日志配置,然后再针对具体的配置做一下说明。如果你对MaxCompute JDBC还不熟悉,那么请在阅读以下内容前先看看这篇《使用 odps-jdbc 接入 ODPS,不再从零开始》。

  1. 取数者

我打算继续以SQL Workbench/J作为例子进行讲解。

SQL Workbench/J 下载到本地后,你会得到一个可执行文件,双击后在弹出界面中点击 Manager Driver 加载我们的 JDBC jar 包。

此处请注意,由于 SQL Workbench/J 自身没有引入 slf4j 的任何日志实现,所以我们可以通过添加 logback 的jar包来启用MaxCompute JDBC默认的logback实现。

然后新建一个 Connection Profile 。请注意在 URL 部分填入的JDBC URL中较之前多了一个名为 log_conf_file的参数:

该参数可用于指定一个本地的 logback 配置文件作为用于MaxCompute JDBC的日志配置。请注意,该参数是一个指定配置文件的参数,而非指定日志输出位置的参数。所以请确保该参数对应的目录下该文件是存在且应用有权限访问的,并且配置文件需要符合logback配置文件的格式。如果不传递该参数,日志将只输出到控制台。而以之前双击方式打开的 SQL Workbench/J 是没有控制台界面的。如果需要将日志输出到特定目录的日志文件中,只需在配置文件中为其添加相应的FileAppender即可。详见第3部分的配置说明。

这一段中提到的JAR包和配置文件请于此处下载:v2.0-beta

  1. 开发者

对于开发者而言,应该对Java的日志框架体系并不陌生,且所开发的应用可能已经使用了 slf4j 及其实现。所以首先需要明确这一点,如果已经使用了 slf4j 及其实现,那么就没有必要再使用JDBC自带的配置功能,可以直接在现有应用的log配置中添加对包com.aliyun.odps.jdbc的日志配置。

如果你没有使用任何的 slf4j 实现,那么请在添加MaxCompute JDBC的JAR包的同时,同时向你的classpath添加logback-core-1.1.7.jar和logback-classic-1.1.7.jar两个JAR包。如果你使用的是maven,可以添加如下依赖:

<dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
            <version>1.1.7</version>
</dependency>

你可以采用两种方式来指定配置文件,一种是直接将logback.xml放入classpath之中。

还有一种方式是以编程的方式,在如下的config中加入了 log_conf_file 属性的配置或是在jdbc URL串中带上 log_conf_file 参数来指定(见之前SQL Workbench/J的示例图)。当你同时在URL和config中配置该项时,以config的值作为优先项使用。

Properties config = new Properties();
config.put("access_id", "...");
config.put("access_key", "...");
config.put("project_name", "...");
config.put("charset", "...");
config.put("log_conf_file","/Users/emerson/logback.xml");
Connection conn = DriverManager.getConnection("jdbc:odps:<endpoint>", config);
  1. 配置说明

接着我们来看看 logback.xml 的内容:

<configuration>
  <appender name="FILE" class="ch.qos.logback.core.FileAppender">
     <!--Linux or Windows:-->
    <!--tries $HOME first; if it doesn't exist, it tries $USERPROFILE-->
    <file>${HOME:-${USERPROFILE}}/logs/odps.log</file>
    <encoder>
      <pattern>%date %level [%thread] %logger{10}  %X{connectionId} [%file:%line] %msg%n</pattern>
    </encoder>
  </appender>

  <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
    <encoder>
      <pattern>%msg%n</pattern>
    </encoder>
  </appender>

<logger name="com.aliyun.odps.jdbc" level="debug"/>

  <root level="error">
    <appender-ref ref="FILE" />
    <appender-ref ref="STDOUT" />
  </root>
</configuration>

这是一个满足基本常规需求的logback配置,如果你没有更多的特殊需求,可以直接复制该配置文件来使用。我将简单对该配置做一下介绍,如果你对logback的配置想要有更深入的了解,请查看官方文档的configuration章节。

其中<configuration>是配置文件的根标签,所有子标签必须包含在根标签之中。其中子标签分为<appender><encoder><logger><root>

Logback 的日志实例是有继承关系的。其中 <root> 就是所有日志实例的父实例,而其余 <logger> 都是子实例,默认都继承父实例的配置。而所有的 <logger> 又根据其 name 属性的前缀来继续维持继承关系,假设这段配置中定义了 com.aliyun.odpscom.aliyun.odps.jdbc 两个日志实例,那后者就是前者的子实例。由于我们目前只有 com.aliyun.odps.jdbc 这个包中有输出日志的代码,所以我们只配置了一个日志实例,它覆盖了 <root>error 日志级别,改为了 debug 级别。

其中日志的输出级别及其严重等级关系为:

TRACE < DEBUG < INFO < WARN < ERROR < OFF

即从左往右的严重等级依次递增,日志数量则依次递减。严重等级越小的日志级别将输出所有大于等于它级别的日志。举个例子,如果你选择DEBUG级别,那除TRACE之外的所有日志都将输出。其中OFF表示不输出日志。

其中的 <encoder> 用于将日志事件编码成字节流,它引用了 <pattern><pattern>表明使用默认的PatternLayout ,其中 <pattern>%date %level [%thread] %logger{10} %X{connectionId} [%file:%line] %msg%n</pattern> 中引用了很多 PatternLayout 中内置的一些变量,用于分别输出日志的日期、级别、线程名、日志实例名、connectionId、类文件、行号、msg信息以及行分隔符。其中更多的内置变量请参阅官方的layouts文档。

这些变量中唯一需要你特别关注的是 %X{connectionId} ,这是一个通过 MDC 设置的每个JDBC Connection唯一的ID,用于标识来自于同一Connection的JDBC日志。

<appender>用于指定日志的输出目标,目前的示例中配置了 FILESTDOUT 两个appender,表明分别将日志输出到文件和标准输出流,其中FILE的appender中又通过 <file> 指明了日志文件的存储路径。

最后我们可以看到日志实例会引用appender,而appender又会引用encoder,从而构造了整个日志配置的体系。

通过以上配置,我们可以在路径/Users/emerson/odps.log下(也就是你的home目录下,上述配置示例中针对Linux和windows的home目录做了兼容)得到格式如下的输出日志:

Logback 是一款相当强大的Java日志框架,你可以通过配置来获取像日志文件rotation、归档,甚至以JMS、邮件方式输出日志等功能。更多的功能请查阅官方文档来获取进一步了解。

欢迎加入MaxCompute钉钉群讨论

时间: 2024-09-30 18:38:18

手把手教你完成MaxCompute JDBC自定义日志配置的相关文章

手把手教你webpack3(9)File-Loader配置简述

FILE-LOADER配置简述 前注: 文档全文请查看 根目录的文档说明. 如果可以,请给本项目加[Star]和[Fork]持续关注. 有疑义请点击这里,发[Issues]. DEMO地址 1.概述 简单来说,file-loader 就是将文件(由于一般是图片文件为主,所以下面通常使用图片两字作为替代,方便理解.其他的包括字体文件等),在进行一些处理后(主要是处理文件名和路径),移动打包后的目录中. 处理的内容包括: 文件名的处理,比如加 [hash] : 路径的处理,比如[把图片文件统一放到i

手把手教你webpack3(11)PostCSS-Loader配置简述

POSTCSS-LOADER配置简述 前注: 文档全文请查看 根目录的文档说明. 如果可以,请给本项目加[Star]和[Fork]持续关注. 有疑义请点击这里,发[Issues]. DEMO地址 1.概述 postcss-loader 用于处理css代码,具有下列特点: 通常由 options 和 plugins 两部分组成,plugins 虽然嵌套在 options 里,但实际上是通过其他插件生效的: 配置是可以独立的(每个配置的插件也是独立的).详细介绍阅读[2.1]: 还有一些自定义配置,

手把手教你webpack3(8)url-Loader配置简述

URL-LOADER配置简述 前注: 文档全文请查看 根目录的文档说明. 如果可以,请给本项目加[Star]和[Fork]持续关注. 有疑义请点击这里,发[Issues]. DEMO地址 1.概述 简单来说,url-loader的效果类似file-loader. 优点: 可以将css文件中的图片链接,转为base64字符串,或移动到打包后文件夹: 缺点: 可配置性比file-loader弱一些,但其实file-loader的那些配置,一般也用不到. 2.配置 2.1.limit 名称 类型 默认

手把手教你webpack3(10)Less-Loader配置简述

LESS-LOADER配置简述 前注: 文档全文请查看 根目录的文档说明. 如果可以,请给本项目加[Star]和[Fork]持续关注. 有疑义请点击这里,发[Issues]. DEMO地址 1.概述 less-loader 用于处理编译 .less 文件,将其转为 css文件代码. 使用 less-loader 的话,必须安装 less,单独一个 less-loader 是没办法正常使用的. 安装 npm install --save less-loader less 2.配置 2.1.无任何配

MaxCompute JDBC 2.0 beta中的一些变更说明

注:MaxCompute原名ODPS,是阿里云自研的大数据计算平台,文中出现的MaxCompute与ODPS都指代同一平台,不做区分 MaxCompute JDBC 2.0 beta 出于易用性的考虑,对配置相关的部分进行了一些变更,大致如下: 添加了对日志配置的支持 新增了配置参数 log_conf_file 用一指定一个本地的配置文件来对日志功能进行定义.该日志功能利用了Java日志框架logback,所以指定的配置文件必须是一个与logback相兼容的配置文件.具体的配置方式见<手把手教你

【中间件3】手把手教你在UbuntuKylin安装配置开源版Tair(请指教)

一 相关资源 1 操作系统环境 2 Tair 资源 二 安装步骤2 1 关闭防火墙3 2 安装工具 3 设置库文件的安装目录 4 编译安装 Tair依赖库tb-common-utils 5 编译安装 Tair 6 配置和启动 tair 三 启动步骤 一 相关资源 1.1 操作系统环境 UbuntuKylin 16.04 64位(x86_64),官方一定要64位的.1 1.2 Tair 资源 Tair 代码 SVN 地址:http://code.taobao.org/svn/tair/trunk/

Android消息推送:手把手教你集成小米推送(附demo)_Android

前言 在Android开发中,消息推送功能的使用非常常见. 为了降低开发成本,使用第三方推送是现今较为流行的解决方案. 今天,我将手把手教大家如何在你的应用里集成小米推送 目录 1. 官方Demo解析 首先,我们先对小米官方的推送Demo进行解析. 请先到官网下载官方Demo和SDK说明文档 1.1 Demo概况 目录说明: DemoApplication类 继承自Application类,其作用主要是:设置App的ID & Key.注册推送服务 DemoMessageReceiver类 继承自

Android消息推送:手把手教你集成小米推送(附demo)

前言 在Android开发中,消息推送功能的使用非常常见. 为了降低开发成本,使用第三方推送是现今较为流行的解决方案. 今天,我将手把手教大家如何在你的应用里集成小米推送 目录 1. 官方Demo解析 首先,我们先对小米官方的推送Demo进行解析. 请先到官网下载官方Demo和SDK说明文档 1.1 Demo概况 目录说明: DemoApplication类 继承自Application类,其作用主要是:设置App的ID & Key.注册推送服务 DemoMessageReceiver类 继承自

手把手教你搭建自己的 VPS 服务器

手把手教你搭建自己的 VPS 服务器 总有一些时候,你想要一台自己的 VPS .本文分享了作者在实践过程中的一些经验,可以给那些自己搭建 VPS 的朋友一点帮助. 前期准备 需要购买一台拥有 root 权限的 VPS ,我选择的是 搬瓦工 ,当时购买的是 512 M 内存 5 G SSD,500 G 流量/月, 9.99 刀每年,但是好像现在这种低价套餐已经结束了.有意的朋友可以看一下其他的套餐或者别的公司的 VPS.有的朋友说  DigitalOcean 的速度非常快,看YouTube直接 1