一个 PostgreSQL 的实例
  作为一个例子,让我们看看 vanilla PostgreSQL 9.4 安装的主配置文件。它叫做 postgresql.conf,与其它Linux 系统中的配置文件不同,它不保存在 /etc 目录下。下列的代码段,我们可以在我们的 Centos 7 服务器的 /var/lib/pgsql 目录下找到它:
  root@localhost ~]# vi /var/lib/pgsql/9.4/data/postgresql.conf
  ...
  #------------------------------------------------------------------------------
  # ERROR REPORTING AND LOGGING
  #------------------------------------------------------------------------------
  # - Where to Log -
  log_destination = 'stderr'     
  # Valid values are combinations of
  # stderr, csvlog, syslog, and eventlog,
  # depending on platform. csvlog
  # requires logging_collector to be on.
  # This is used when logging to stderr:
  logging_collector = on         
  # Enable capturing of stderr and csvlog
  # into log files. Required to be on for
  # csvlogs.
  # (change requires restart)
  # These are only used if logging_collector is on:
  log_directory = 'pg_log'      
  # directory where log files are written,
  # can be absolute or relative to PGDATA
  log_filename = 'postgresql-%a.log'    # log file name pattern,
  # can include strftime() escapes
  # log_file_mode = 0600           .
  # creation mode for log files,
  # begin with 0 to use octal notation
  log_truncate_on_rotation = on   # If on, an existing log file with the
  # same name as the new log file will be
  # truncated rather than appended to.
  # But such truncation only occurs on
  # time-driven rotation, not on restarts
  # or size-driven rotation. Default is
  # off, meaning append to existing files
  # in all cases.
  log_rotation_age = 1d          
  # Automatic rotation of logfiles will happen after that time. 0 disables.
  log_rotation_size = 0           # Automatic rotation of logfiles will happen after that much log output. 0 disables.
  # These are relevant when logging to syslog:
  #syslog_facility = 'LOCAL0'
  #syslog_ident = 'postgres'
  # This is only relevant when logging to eventlog (win32):
  #event_source = 'PostgreSQL'
  # - When to Log -
  #client_min_messages = notice   # values in order of decreasing detail:
  # debug5
  # debug4
  # debug3
  # debug2
  # debug1
  # log
  # notice
  # warning
  # error
  #log_min_messages = warning     # values in order of decreasing detail:
  # debug5
  # debug4
  # debug3
  # debug2
  # debug1
  # info
  # notice
  # warning
  # error
  # log
  # fatal
  # panic
  #log_min_error_statement = error    # values in order of decreasing detail:
  # debug5
  # debug4
  # debug3
  # debug2
  # debug1
  # info
  # notice
  # warning
  # error
  # log
  # fatal
  # panic (effectively off)
  #log_min_duration_statement = -1     # -1 is disabled, 0 logs all statements
  # and their durations, > 0 logs only
  # statements running at least this number
  # of milliseconds
  # - What to Log
  #debug_print_parse = off
  #debug_print_rewritten = off
  #debug_print_plan = off
  #debug_pretty_print = on
  #log_checkpoints = off
  #log_connections = off
  #log_disconnections = off
  #log_duration = off
  #log_error_verbosity = default   
  # terse, default, or verbose messages
  #log_hostname = off
  log_line_prefix = '< %m >'          # special values:
  # %a = application name
  # %u = user name
  # %d = database name
  # %r = remote host and port
  # %h = remote host
  # %p = process ID
  # %t = timestamp without milliseconds
  # %m = timestamp with milliseconds
  # %i = command tag
  # %e = SQL state
  # %c = session ID
  # %l = session line number
  # %s = session start timestamp
  # %v = virtual transaction ID
  # %x = transaction ID (0 if none)
  # %q = stop here in non-session
  # processes
  # %% = '%'
  # e.g. '<%u%%%d> '
  #log_lock_waits = off               # log lock waits >= deadlock_timeout
  #log_statement = 'none'             # none, ddl, mod, all
  #log_temp_files = -1                # log temporary files equal or larger
  # than the specified size in kilobytes;5# -1 disables, 0 logs all temp files5
  log_timezone = 'Australia/ACT'
  虽然大多数参数被加上了注释,它们使用了默认值。我们可以看见日志文件目录是 pglog(logdirectory 参数,在 /var/lib/pgsql/9.4/data/ 下的子目录),文件名应该以 postgresql 开头(logfilename参数),文件每天轮转一次(logrotationage 参数)然后每行日志记录以时间戳开头(loglineprefix参数)。特别值得说明的是 logline_prefix 参数:全部的信息你都可以包含在这。
  看 /var/lib/pgsql/9.4/data/pg_log 目录下展现给我们这些文件:
  [root@localhost ~]# ls -l /var/lib/pgsql/9.4/data/pg_log
  total 20
  -rw-------. 1 postgres postgres 1212 May 1 20:11 postgresql-Fri.log
  -rw-------. 1 postgres postgres 243 Feb 9 21:49 postgresql-Mon.log
  -rw-------. 1 postgres postgres 1138 Feb 7 11:08 postgresql-Sat.log
  -rw-------. 1 postgres postgres 1203 Feb 26 21:32 postgresql-Thu.log
  -rw-------. 1 postgres postgres 326 Feb 10 01:20 postgresql-Tue.log
  所以日志文件名只有星期命名的标签。我们可以改变它。如何做?在 postgresql.conf 配置 log_filename 参数。
  查看一个日志内容,它的条目仅以日期时间开头:
  [root@localhost ~]# cat /var/lib/pgsql/9.4/data/pg_log/postgresql-Fri.log
  ...
  < 2015-02-27 01:21:27.020 EST >LOG: received fast shutdown request
  < 2015-02-27 01:21:27.025 EST >LOG: aborting any active transactions
  < 2015-02-27 01:21:27.026 EST >LOG: autovacuum launcher shutting down
  < 2015-02-27 01:21:27.036 EST >LOG: shutting down
  < 2015-02-27 01:21:27.211 EST >LOG: database system is shut down
  归集应用的日志
  使用 imfile 监控日志
  习惯上,应用通常记录它们数据在文件里。文件容易在一个机器上寻找,但是多台服务器上不是很恰当了。你可以设置日志文件监控,然后当新的日志被添加到文件尾部后发送事件到一个集中服务器。在 /etc/rsyslog.d/ 里创建一个新的配置文件然后增加一个配置文件,然后输入如下:
  $ModLoad imfile
  $InputFilePollInterval 10
  $PrivDropToGroup adm
  # Input for FILE1
  $InputFileName /FILE1
  $InputFileTag APPNAME1
  $InputFileStateFile stat-APPNAME1 #this must be unique for each file being polled
  $InputFileSeverity info
  $InputFilePersistStateInterval 20000
  $InputRunFileMonitor
  替换 FILE1 和 APPNAME1 为你自己的文件名和应用名称。rsyslog 将发送它到你配置的输出目标中。
  本地套接字日志与 imuxsock
  套接字类似 UNIX 文件句柄,所不同的是套接字内容是由 syslog 守护进程读取到内存中,然后发送到目的地。不需要写入文件。作为一个例子,logger 命令发送它的日志到这个 UNIX 套接字。
  如果你的服务器 I/O 有限或者你不需要本地文件日志,这个方法可以使系统资源有效利用。这个方法缺点是套接字有队列大小的限制。如果你的 syslog 守护进程宕掉或者不能保持运行,然后你可能会丢失日志数据。
  rsyslog 程序将默认从 /dev/log 套接字中读取,但是你需要使用如下命令来让 imuxsock 输入模块 启用它:
  $ModLoad imuxsock
  UDP 日志与 imupd
  一些应用程序使用 UDP 格式输出日志数据,这是在网络上或者本地传输日志文件的标准 syslog 协议。你的 syslog 守护进程接受这些日志,然后处理它们或者用不同的格式传输它们。备选的,你可以发送日志到你的日志服务器或者到一个日志管理方案中。
  使用如下命令配置 rsyslog 通过 UDP 来接收标准端口 514 的 syslog 数据:
  $ModLoad imudp
  $UDPServerRun 514
  用 logrotate 管理日志
  日志轮转是当日志到达指定的时期时自动归档日志文件的方法。如果不介入,日志文件一直增长,会用尽磁盘空间。后它们将破坏你的机器。
  logrotate 工具能随着日志的日期截取你的日志,腾出空间。你的新日志文件保持该文件名。你的旧日志文件被重命名加上后缀数字。每次 logrotate 工具运行,会创建一个新文件,然后现存的文件被逐一重命名。你来决定何时旧文件被删除或归档的阈值。
  当 logrotate 拷贝一个文件,新的文件会有一个新的 inode,这会妨碍 rsyslog 监控新文件。你可以通过增加copytruncate 参数到你的 logrotate 定时任务来缓解这个问题。这个参数会拷贝现有的日志文件内容到新文件然后从现有文件截短这些内容。因为日志文件还是同一个,所以 inode 不会改变;但它的内容是一个新文件。
  logrotate 工具使用的主配置文件是 /etc/logrotate.conf,应用特有设置在 /etc/logrotate.d/ 目录下。DigitalOcean 有一个详细的 logrotate 教程
  管理很多服务器的配置
  当你只有很少的服务器,你可以登录上去手动配置。一旦你有几打或者更多服务器,你可以利用工具的优势使这变得更容易和更可扩展。基本上,所有的事情是拷贝你的 rsyslog 配置到每个服务器,然后重启 rsyslog 使更改生效。
  pssh
  这个工具可以让你在很多服务器上并行的运行一个 ssh 命令。使用 pssh 部署仅用于少量服务器。如果你其中一个服务器失败,然后你必须 ssh 到失败的服务器,然后手动部署。如果你有很多服务器失败,那么手动部署它们会话费很长时间。
  Puppet/Chef
  Puppet 和 Chef 是两个不同的工具,它们能在你的网络按你规定的标准自动的配置所有服务器。它们的报表工具可以使你了解错误情况,然后定期重新同步。Puppet 和 Chef 都有一些狂热的支持者。如果你不确定那个更适合你的部署配置管理,你可以拜读一下 InfoWorld 上这两个工具的对比
  一些厂商也提供一些配置 rsyslog 的模块或者方法。这有一个 Loggly 上 Puppet 模块的例子。它提供给 rsyslog 一个类,你可以添加一个标识令牌:
  node 'my_server_node.example.net' {
  # Send syslog events to Loggly
  class { 'loggly::rsyslog':
  customer_token => 'de7b5ccd-04de-4dc4-fbc9-501393600000',
  }
  }
  Docker
  Docker 使用容器去运行应用,不依赖于底层服务。所有东西都运行在内部的容器,你可以把它想象为一个功能单元。ZDNet 有一篇关于在你的数据中心使用 Docker 的深入文章。
  这里有很多方式从 Docker 容器记录日志,包括链接到一个日志容器,记录到一个共享卷,或者直接在容器里添加一个 sysllog 代理。其中流行的日志容器叫做 logspout。
  供应商的脚本或代理
  大多数日志管理方案提供一些脚本或者代理,可以从一个或更多服务器相对容易地发送数据。重量级代理会耗尽额外的系统资源。一些供应商像 Loggly 提供配置脚本,来使用现存的 syslog 守护进程更轻松。这有一个 Loggly 上的例子脚本,它能运行在任意数量的服务器上。