nginx 直接向 logstash 发送 JSON 格式日志

通过 nginx 的 log_format 指令可以很容易直接就在 nginx 这里就生成(几乎是)JSON 格式的消息发送到 logstash

log_format  logstash '{"@timestamp":"$time_iso8601",'
                     '"@version":"1",'
                     '"host":"$server_addr",'
                     '"client":"$remote_addr",'
                     '"size":$body_bytes_sent,'
                     '"domain":"$host",'
                     '"method":"$request_method",'
                     '"url":"$uri",'
                     '"status":"$status",' # status 有可能会是以0开头,比如“009”这样的状态码,因此不能以数值形式保存,需要加括号存为字符串
                     '"referer":"$http_referer",'
                     '"user_agent":"$http_user_agent",'
                     '"real_ip":"$http_x_real_ip",'
                     '"forwarded_for":"$http_x_forwarded_for",'
                     '"responsetime":$request_time,'
                     '"upstream":"$upstream_addr",'
                     '"upstream_response_time":"$upstream_response_time",'
                     '"cache_fetch":"$srcache_fetch_status",' # 统计srcahe缓存命中率
                     '"cache_store":"$srcache_store_status"}';

但是这个还是会有问题,因为中文字符编码的原因,有时候 url 或者 referer 头里面可能会出现”\x”这样的跳脱字符,导致 JSON 解析失败,这个时候需要在 logstash 的 filter 里面再加上配置

filter {
  if [type] == "nginx-access-syslog" {
    mutate {
      gsub => [
        # replace '\x' with '\\x', or json parser will fail
        "message", "\\x", "\\\\x"
      ]
    }
  }
}

把”\x”替换为”\\x”。(这个方法不通用,只对”\x”做了处理,但一般应该也只有”\x”会出现了。。。)
然后我们可以用 kibana 画图了,以上收集的参数还算比较丰富了,可以做出很不错的 dashboard 了

Android 系统更新,愿你一直这么蠢下去

最近 Android 6.0 版本发布了,而我正好有一个Nexus 7 2013,但我却还无法更新它的系统,因为 Google 的傻逼 OTA 更新方式,服务器那头拒绝给我检测到更新。

这当然不是我第一次遇到这种情况了,以前的每次系统更新也是一样,Android 升级的主动权完全不由用户掌握。

Android 系统更新本来就是个老大难的问题,但我实在想不出 Google 的人是怎么想的,就算是官方支持的设备其实也无法及时更新到最新版本的系统。

  • 如果 Google 是想采用灰度发布,那么其实根本就不应该发布。这么做只不过是先拿一部分用户直接来当小白鼠来测试你的系统而已,所有用户的设备都该被当成重要的,你应该事先完全测试好。
  • 如果 Google 是因为服务器带宽资源不足够以立即对所有用户分发,我其实不太相信这种原因。
  • 为甚么不提供方式让用户自己使用其它方式下载安装包手动更新

以上,Apple 实在做得比 Google 好得多,新版本发布后可以立即更新,无论是 OTA 还是自己本地下载更新。