script day.log

大学生がなんとなく始めた、趣味やら生活のことを記録していく。

fluentd + elasticsearch + kibanaによるログ監視環境構築

少し前よりログ監視はしなければならず,
新規に環境を構築した際にインストールメモを作成したのですが,
折角なのでこちらにも記載しようと思います.

ちなみに先日参加した卒論聴講会ではトラフィックの可視化?というテーマがあったのですが,
どういった環境の可視化を行ったのか,非常に気になるところです.

それでは本編です.

how to install

1.Server: fluentd + elasticsearch + kibana

1.1 fluentd setup (Quickstart Guide | Fluentd)

Step1: install
# Amazon Linux 1
$ curl -L https://toolbelt.treasuredata.com/sh/install-amazon1-td-agent3.sh | sh
# Amazon Linux 2
$ curl -L https://toolbelt.treasuredata.com/sh/install-amazon2-td-agent3.sh | sh
$ curl -L https://toolbelt.treasuredata.com/sh/install-redhat-td-agent3.sh | sh
Step2: Launch Daemon
  • systemed
$ sudo systemctl start td-agent.service
$ sudo systemctl status td-agent.service
  • init.d
$ /etc/init.d/td-agent start 
$ /etc/init.d/td-agent status

1.2 elasticsearch setup (Install Elasticsearch with RPM | Elasticsearch Reference [6.2] | Elastic)

Step1: Java8 install

elasticsearch need java8

$ sudo yum install java-1.8.0-openjdk-devel
$ sudo alternatives --config java //java-1.8.0 select
$ java --version
Step2: elasticsearch install

Download and install the public signing key

$ rpm --import https://artifacts.elastic.co/GPG-KEY-elasticsearch
$ sudo yum install elasticsearch
Step3: Launch Daemon
  • systemed
$ sudo systemctl daemon-reload

$ sudo systemctl start elasticsearch.service
$ sudo systemctl enable elasticsearch.service
$ sudo systemctl status elasticsearch.service
  • init.d
$ /etc/init.d/elasticsearch start 
$ /etc/init.d/elasticsearch status
or
$ sudo -i service elasticsearch start
$ sudo -i service elasticsearch status

$ sudo chkconfig --add elasticsearch
Step 4: X-Pack install (Installing X-Pack in Elasticsearch | Elasticsearch Reference [6.2] | Elastic)
$ cd /usr/share/elasticsearch
$ sudo bin/elasticsearch-plugin install x-pack
Step 5: Password Setup for X-Pack (Getting Started with Security | X-Pack for the Elastic Stack [6.2] | Elastic)
$ cd /usr/share/elasticsearch
$ bin/x-pack/setup-passwords auto
Directory layout of RPM
type Description Default Location Setting
home elasticsearch home directory or $ES_HOME /usr/share/elasticsearch
bin Binary scripts including elasticsearch to start a node and elasticsearch-plugin to install plugins /usr/share/elasticsearch/bin
conf Configuration files including elasticsearch.yml /etc/elasticsearch ES_PATH_CONF
conf CEnvironment variables including heap size, file descriptors. /etc/sysconfig/elasticsearch
data The location of the data files of each index / shard allocated on the node. Can hold multiple locations. /var/lib/elasticsearch path.data
logs Log files location. /var/log/elasticsearch path.logs
plugins Plugin files location. Each plugin will be contained in a subdirectory. /usr/share/elasticsearch/plugins
repo Shared file system repository locations. Can hold multiple locations. A file system repository can be placed in to any subdirectory of any directory specified here. Not configured path.repo

1.3 kibana setup (Install Kibana with RPM | Kibana User Guide [6.2] | Elastic)

Step1: kibana install

Download and install the public signing key

$ sudo yum install kibana
Step2: Launch Daemon

systemed ? init.d ? use this command

$ ps -p 1
  • systemed
$ sudo systemctl daemon-reload

$ sudo systemctl start kibana.service
$ sudo systemctl enable kibana.service
$ sudo systemctl status kibana.service
  • init.d
$ /etc/init.d/kibana start 
$ /etc/init.d/kibana status
or
$ sudo -i service kibana start
$ sudo -i service kibana status

$ sudo chkconfig --add kibana
Step 3: X-Pack install (Installing X-Pack in Kibana | Kibana User Guide [6.2] | Elastic)
$ cd /usr/share/kibana
$ sudo bin/kibana-plugin install x-pack
Step 4: kibana.yml edit
elasticsearch.username: "kibana"
elasticsearch.password: "<kibanapassword">
Directory layout of RPM
type Description Default Location Setting
home Kibana home directory or $KIBANA_HOME /usr/share/kibana
bin Binary scripts including kibana to start the Kibana server and kibana-plugin to install plugins /usr/share/kibana/bin
config Configuration files including kibana.yml /etc/kibana
data The location of the data files written to disk by Kibana and its plugins /var/lib/kibana path.data
optimize Transpiled source code. Certain administrative actions (e.g. plugin install) result in the source code being retranspiled on the fly. /usr/share/kibana/optimize
plugins Plugin files location. Each plugin will be contained in a subdirectory. /usr/share/kibana/plugins

2.elasticsearch settings

make template for elasticsearch

$ vi es_rtx1200_template.json
$ curl -u elastic:<elasticpassword> -H "Content-Type: application/json" -XPUT 127.0.0.1:9200/rtx1200/ -d "`cat es_rtx1200_template.json`"
$ vi es_apache_template.json
$ curl -u elastic:<elasticpassword> -H "Content-Type: application/json" -XPUT 127.0.0.1:9200/apache/ -d "`cat es_apache_template.json`"
$ vi es_nas_template.json
$ curl -u elastic:<elasticpassword> -H "Content-Type: application/json" -XPUT 127.0.0.1:9200/nas/ -d "`cat es_nas_template.json`"
  • es_rtx1200_template.json
elasticsearch_rtx_template.json
{
    "templete": "rtx1200-*",
    "mappings": {
        "_default_": {
            "dynamic_templates": [
                {
                    "string_template" : {
                        "match" : "*",
                        "mapping": {
                            "type": "string",
                            "fields": {
                                "full": {
                                    "type": "string",
                                    "index": "false"
                                }
                            }
                        },
                        "match_mapping_type": "string"
                    }
                }
            ],
            "properties": {
                "@timestamp": { "type": "date", "index": "false" },
                "geo_location": {"type" : "geo_point" }
            }
        }
    }
}
elasticsearch_apache_template.json
{
    "templete": "*.apache-*”,
    "mappings": {
        "_default_": {
            "dynamic_templates": [
                {
                    "string_template" : {
                        "match" : "*",
                        "mapping": {
                            "type": "string",
                            "fields": {
                                "full": {
                                    "type": "string",
                                    "index": "false"
                                }
                            }
                        },
                        "match_mapping_type": "string"
                    }
                }
            ],
            "properties": {
                "@timestamp": { "type": "date", "index": "false" }
            }
        }
    }
}
 
{
    "templete": "myhome-nas-*",
    "mappings": {
        "_default_": {
            "dynamic_templates": [
                {
                    "string_template" : {
                        "match" : "*",
                        "mapping": {
                            "type": "string",
                            "fields": {
                                "full": {
                                    "type": "string",
                                    "index": "false"
                                }
                            }
                        },
                        "match_mapping_type": "string"
                    }
                }
            ],
            "properties": {
                "@timestamp": { "type": "date", "index": "false" }
            }
        }
    }
}

3.fluentd settings

3.fluentd settings

3.1 fluentd-plugin install

$ td-agent-gem install fluent-plugin-rewrite-tag-filter
$ td-agent-gem install fluent-plugin-elasticsearch

$ yum install geoip-devel
$ td-agent-gem install fluent-plugin-geoip -v 0.8.0

$ td-agent-gem install fluent-plugin-multi-format-parser
$ td-agent-gem install fluent-plugin-parser
$ td-agent-gem install fluent-plugin-with-extra-fields-parser

3.2 edit td-agent.conf

td-agent.conf location /etc/td-agent/td-agent.conf

  • index filter
1.rtx1200
# dynamic filter ==> rtx-1200-inspect
# filter reject ==> rtx1200-reject
# console log in/out ==> rtx1200-console
# VPN access on/off ==> rtx1200-tunnel
# others ==> rtx1200-other
2.nas
# all ==> myhome-nas
3.apache
# access_log ==> <prefix>.apache-access
# error_log ==> <prefix>.apache-error
  • td-agent.conf
####
## Source descriptions:
##

## syslog
<source>
  @type tail
  tag raw.rtx1200
  format none
  path /var/log/syslog
  pos_file /var/log/td-agent/syslog.pos
</source>

<source>
  @type forward
  port 24224
  bind 0.0.0.0
  tag log.apache.242
</source>

<source>
  @type forward
  port 24225
  bind 0.0.0.0
  tag log.apache.app
</source>

<source>
  @type forward
  port 24226
  bind 0.0.0.0
  tag log.apache.s
</source>

<source>
  @type forward
  port 24227
  bind 0.0.0.0
  tag log.apache.piro
</source>

####
## Output descriptions:
##
<match raw.rtx1200.**>
  type parser
  format multi_format
  key_name message
  remove_prefix raw
  add_prefix parsed
  <pattern>
      format with_extra_fields
      base_format /\[INSPECT\]\s+(?<target>.+)\[(?<direction>.+)\]\[(?<filter_num>\d+)\]\s+(?<proto>.+)\s+(?<src_ip>.+):(?<src_port>.+)\s+>\s+(?<dest_ip>.+):(?<dest_port>.+)\s+\((?<time>.+)\)$/
      time_format '%Y/%m/%d %H:%M:%S'
      extra_fields { "log_type": "inspect" }
  </pattern>
  <pattern>
      format with_extra_fields
      base_format /(?<target>.+)\s+Rejected\s+at\s+(?<direction>.+)\s+filter:\s+(?<proto>.+)\s+(?<src_ip>.+):(?<src_port>.+)\s+>\s+(?<dest_ip>.+):(?<dest_port>.+)$/
      extra_fields { "log_type": "reject" }
  </pattern>
  <pattern>
      format with_extra_fields
      base_format /Logout\s+from\s+(?<proto>.+):\s+(?<ip>.+)$/
      extra_fields { "log_type": "console_logout" }
  </pattern>
  <pattern>
      format with_extra_fields
      base_format /Login\s+succeeded\s+for\s+(?<proto>.+):\s+(?<ip>.+)$/
      extra_fields { "log_type": "console_login" }
  </pattern>
  <pattern>
      format with_extra_fields
      base_format /\[(?<proto>.+)\]\s+(?<tunnel>.+)\s+connected\s+from\s+(?<src_ip>.+)$/
      extra_fields { "log_type": "tunnel_connect" }
  </pattern>
  <pattern>
      format with_extra_fields
      base_format /\[(?<proto>.+)\]\s+(?<tunnel>.+)\s+disconnect\s+tunnel\s+\d+\s+complete$/
      extra_fields { "log_type": "tunnel_disconnect" }
  </pattern>
   <pattern>
      format with_extra_fields
      base_format /PP\[.*\]\s+Call\s+detected\s+from\s+user\s+\W(?<user>.+)\W$/
      extra_fields { "log_type": "vpnuser" }
  </pattern>
  <pattern>
     format with_extra_fields
     base_format /(?<date>.+)\s(?<machine>eymovic-NAS)\sqlogd\[\d+\]:\s(?<log>.+):\sUsers:\s(?<Users>.+),\sSource\sIP:\s(?<src_ip>.+),\sComputer\sname:\s(?<computer_name>.+),\sConnection\stype:\s(?<connection_type>.+),\sAccessed\sresources:\s(?<accessed_resources>.+),\sAction:\s(?<action>.+)$/
     extra_fields { "log_type": "NAS" }
  </pattern>
  <pattern>
      format with_extra_fields
      base_format /(?<msg>.+)$/
      extra_fields { "log_type": "other" }
  </pattern>

</match>

<match parsed.rtx1200.**>
  type rewrite_tag_filter
  <rule>
  key     log_type
  pattern ^inspect$
  tag     rtx1200.inspect
  </rule>
  <rule>
  key     log_type
  pattern ^reject$
  tag     temp.rtx1200.reject
  </rule>
  <rule>
  key     log_type
  pattern ^console_(.+)$
  tag     rtx1200.console.$1
  </rule>
  <rule>
  key     log_type
  pattern ^tunnel_(.+)$
  tag     temp.rtx1200.tunnel.$1
  </rule>
  <rule>
  key     log_type
  pattern ^vpnuser$
  tag     rtx1200.vpnuser
  </rule>
  <rule>
  key     log_type
  pattern ^NAS$
  tag     myhome.nas
  </rule>
  <rule>
  key     log_type
  pattern ^other$
  tag     rtx1200.other
  </rule>
</match>

<match rtx1200.inspect.**>
  type elasticsearch
  logstash_format true
  logstash_prefix rtx1200-inspect
  include_tag_key true
  tag_key @log_name
  hosts localhost:9200
  buffer_type memory
  num_threads 1
  flush_interval 60
  retry_wait 1.0
  retry_limit 17
  user elastic
  password <elasticsearch password>
</match>

<match temp.rtx1200.reject.**>
  type  geoip
  geoip_lookup_key src_ip
  <record>
    geo_location  '{ "lat" : ${latitude["src_ip"]}, "lon" : ${longitude["src_ip"]} }'
    country_code  ${country_code["src_ip"]}
  </record>
  remove_tag_prefix temp.
  skip_adding_null_record  true
  flush_interval 1s
</match>
<match rtx1200.reject.**>
  type elasticsearch
  logstash_format true
  logstash_prefix rtx1200-reject
  include_tag_key true
  tag_key @log_name
  hosts localhost:9200
  buffer_type memory
  num_threads 1
  flush_interval 60
  retry_wait 1.0
  retry_limit 17
  user elastic
  password <elasticsearch password>
</match>

<match rtx1200.console.**>
  type elasticsearch
  logstash_format true
  logstash_prefix rtx1200-console
  include_tag_key true
  tag_key @log_name
  hosts localhost:9200
  buffer_type memory
  num_threads 1
  flush_interval 60
  retry_wait 1.0
  retry_limit 17
  user elastic
  password <elasticsearch password>
</match>

<match temp.rtx1200.tunnel.**>
  type  geoip
  geoip_lookup_key src_ip
  <record>
    geo_location  '{ "lat" : ${latitude["src_ip"]}, "lon" : ${longitude["src_ip"]} }'
    country_code  ${country_code["src_ip"]}
  </record>
  remove_tag_prefix temp.
  skip_adding_null_record  true
  flush_interval 1s
</match>
<match rtx1200.tunnel.**>
  type elasticsearch
  logstash_format true
  logstash_prefix rtx1200-tunnel
  include_tag_key true
  tag_key @log_name
  hosts localhost:9200
  buffer_type memory
  num_threads 1
  flush_interval 60
  retry_wait 1.0
  retry_limit 17
  user elastic
  password <elasticsearch password>
</match>

<match rtx1200.vpnuser.**>
  type elasticsearch
  logstash_format true
  logstash_prefix rtx1200-vpnuser
  include_tag_key true
  tag_key @log_name
  hosts localhost:9200
  buffer_type memory
  num_threads 1
  flush_interval 60
  retry_wait 1.0
  retry_limit 17
  user elastic
  password <elasticsearch password>
</match>

<match rtx1200.other.**>
  type elasticsearch
  logstash_format true
  logstash_prefix rtx1200-other
  include_tag_key true
  tag_key @log_name
  hosts localhost:9200
  buffer_type memory
  num_threads 1
  flush_interval 60
  retry_wait 1.0
  retry_limit 17
  user elastic
  password <elasticsearch password>
</match>

<match myhome.nas.**>
  type elasticsearch
  logstash_format true
  logstash_prefix myhome-nas
  include_tag_key true
  tag_key @log_name
  hosts localhost:9200
  buffer_type memory
  num_threads 1
  flush_interval 60
  retry_wait 1.0
  retry_limit 17
  user elastic
  password <elasticsearch password>
</match>

<match log.apache.242.**>
  type parser
  format multi_format
  key_name message
  remove_prefix log
  add_prefix parsed
  <pattern>
      # format with_extra_fields
      # base_format /(?<src_ip>.+)\s-\s-\s\[(?<date>.+)\]\s\"(?<method>.+)\".*\"(?<dest_url>.+)\"\s\"(?<browser>.+)\"/
      # time_format '%Y/%m/%d %H:%M:%S'
      format with_extra_fields
      base_format /^(?<host>[^ ]*) [^ ]* (?<user>[^ ]*) \[(?<time>[^\]]*)\] "(?<method>\S+)(?: +(?<path>[^ ]*) +\S*)?" (?<code>[^ ]*) (?<size>[^ ]*)(?: "(?<referer>[^\"]*)" "(?<agent>[^\"]*)")?$/
      time_format %d/%b/%Y:%H:%M:%S %z
      extra_fields { "log_type": "access" }
  </pattern>
  <pattern>
      # format with_extra_fields
      # base_format /\[(?<date>.+)\]\s\[(?<event>.+)\]\s\[.+\]\s(?<message>.+)/
      # time_format '%Y/%m/%d %H:%M:%S'
      format with_extra_fields
      base_format /^\[[^ ]* (?<time>[^\]]*)\] \[(?<level>[^\]]*)\](?: \[pid (?<pid>[^\]]*)\])? \[client (?<client>[^\]]*)\] (?<message>.*)$/
      time_format %d/%b/%Y:%H:%M:%S %z
      extra_fields { "log_type": "error" }
  </pattern>
</match>

<match parsed.apache.242.**>
  type rewrite_tag_filter
  <rule>
  key     log_type
  pattern ^access$
  tag     242.apache.access
  </rule>
  <rule>
  key     log_type
  pattern ^error$
  tag     242.apache.error
  </rule>
</match>

<match 242.apache.access>
    type elasticsearch
    logstash_format true
    logstash_prefix 242.apache-access
    include_tag_key true
    tag_key @log_name
    hosts localhost:9200
    buffer_type memory
    num_threads 1
    flush_interval 60
    retry_wait 1.0
    retry_limit 17
    user elastic
    password <elasticsearch password>
</match>

<match 242.apache.error>
    type elasticsearch
    logstash_format true
    logstash_prefix 242.apache-error
    include_tag_key true
    tag_key @log_name
    hosts localhost:9200
    buffer_type memory
    num_threads 1
    flush_interval 60
    retry_wait 1.0
    retry_limit 17
    user elastic
    password <elasticsearch password>
</match>

<match log.apache.app.**>
  type parser
  format multi_format
  key_name message
  remove_prefix log
  add_prefix parsed
  <pattern>
      # format with_extra_fields
      # base_format /(?<src_ip>.+)\s-\s-\s\[(?<date>.+)\]\s\"(?<method>.+)\".*\"(?<dest_url>.+)\"\s\"(?<browser>.+)\"/
      # time_format '%Y/%m/%d %H:%M:%S'
      format with_extra_fields
      base_format /^(?<host>[^ ]*) [^ ]* (?<user>[^ ]*) \[(?<time>[^\]]*)\] "(?<method>\S+)(?: +(?<path>[^ ]*) +\S*)?" (?<code>[^ ]*) (?<size>[^ ]*)(?: "(?<referer>[^\"]*)" "(?<agent>[^\"]*)")?$/
      time_format %d/%b/%Y:%H:%M:%S %z
      extra_fields { "log_type": "access" }
  </pattern>
  <pattern>
      # format with_extra_fields
      # base_format /\[(?<date>.+)\]\s\[(?<event>.+)\]\s\[.+\]\s(?<message>.+)/
      # time_format '%Y/%m/%d %H:%M:%S'
      format with_extra_fields
      base_format /^\[[^ ]* (?<time>[^\]]*)\] \[(?<level>[^\]]*)\](?: \[pid (?<pid>[^\]]*)\])? \[client (?<client>[^\]]*)\] (?<message>.*)$/
      time_format %d/%b/%Y:%H:%M:%S %z
      extra_fields { "log_type": "error" }
  </pattern>
</match>

<match parsed.apache.app.**>
  type rewrite_tag_filter
  <rule>
  key     log_type
  pattern ^access$
  tag     app.apache.access
  </rule>
  <rule>
  key     log_type
  pattern ^error$
  tag     app.apache.error
  </rule>
</match>

<match app.apache.access>
    type elasticsearch
    logstash_format true
    logstash_prefix app.apache-access
    include_tag_key true
    tag_key @log_name
    hosts localhost:9200
    buffer_type memory
    num_threads 1
    flush_interval 60
    retry_wait 1.0
    retry_limit 17
    user elastic
    password <elasticsearch password>
</match>

<match app.apache.error>
    type elasticsearch
    logstash_format true
    logstash_prefix app.apache-error
    include_tag_key true
    tag_key @log_name
    hosts localhost:9200
    buffer_type memory
    num_threads 1
    flush_interval 60
    retry_wait 1.0
    retry_limit 17
    user elastic
    password <elasticsearch password>
</match>

<match log.apache.s.**>
  type parser
  format multi_format
  key_name message
  remove_prefix log
  add_prefix parsed
  <pattern>
      # format with_extra_fields
      # base_format /(?<src_ip>.+)\s-\s-\s\[(?<date>.+)\]\s\"(?<method>.+)\".*\"(?<dest_url>.+)\"\s\"(?<browser>.+)\"/
      # time_format '%Y/%m/%d %H:%M:%S'
      format with_extra_fields
      base_format /^(?<host>[^ ]*) [^ ]* (?<user>[^ ]*) \[(?<time>[^\]]*)\] "(?<method>\S+)(?: +(?<path>[^ ]*) +\S*)?" (?<code>[^ ]*) (?<size>[^ ]*)(?: "(?<referer>[^\"]*)" "(?<agent>[^\"]*)")?$/
      time_format %d/%b/%Y:%H:%M:%S %z
      extra_fields { "log_type": "access" }
  </pattern>
  <pattern>
      # format with_extra_fields
      # base_format /\[(?<date>.+)\]\s\[(?<event>.+)\]\s\[.+\]\s(?<message>.+)/
      # time_format '%Y/%m/%d %H:%M:%S'
      format with_extra_fields
      base_format /^\[[^ ]* (?<time>[^\]]*)\] \[(?<level>[^\]]*)\](?: \[pid (?<pid>[^\]]*)\])? \[client (?<client>[^\]]*)\] (?<message>.*)$/
      time_format %d/%b/%Y:%H:%M:%S %z
      extra_fields { "log_type": "error" }
  </pattern>
</match>

<match parsed.apache.s.**>
  type rewrite_tag_filter
  <rule>
  key     log_type
  pattern ^access$
  tag     s.apache.access
  </rule>
  <rule>
  key     log_type
  pattern ^error$
  tag     s.apache.error
  </rule>
</match>

<match s.apache.access>
    type elasticsearch
    logstash_format true
    logstash_prefix s.apache-access
    include_tag_key true
    tag_key @log_name
    hosts localhost:9200
    buffer_type memory
    num_threads 1
    flush_interval 60
    retry_wait 1.0
    retry_limit 17
    user elastic
    password <elasticsearch password>
</match>

<match s.apache.error>
    type elasticsearch
    logstash_format true
    logstash_prefix s.apache-error
    include_tag_key true
    tag_key @log_name
    hosts localhost:9200
    buffer_type memory
    num_threads 1
    flush_interval 60
    retry_wait 1.0
    retry_limit 17
    user elastic
    password <elasticsearch password>
</match>

<match log.apache.piro.**>
  type parser
  format multi_format
  key_name message
  remove_prefix log
  add_prefix parsed
  <pattern>
      # format with_extra_fields
      # base_format /(?<src_ip>.+)\s-\s-\s\[(?<date>.+)\]\s\"(?<method>.+)\".*\"(?<dest_url>.+)\"\s\"(?<browser>.+)\"/
      # time_format '%Y/%m/%d %H:%M:%S'
      format with_extra_fields
      base_format /^(?<host>[^ ]*) [^ ]* (?<user>[^ ]*) \[(?<time>[^\]]*)\] "(?<method>\S+)(?: +(?<path>[^ ]*) +\S*)?" (?<code>[^ ]*) (?<size>[^ ]*)(?: "(?<referer>[^\"]*)" "(?<agent>[^\"]*)")?$/
      time_format %d/%b/%Y:%H:%M:%S %z
      extra_fields { "log_type": "access" }
  </pattern>
  <pattern>
      # format with_extra_fields
      # base_format /\[(?<date>.+)\]\s\[(?<event>.+)\]\s\[.+\]\s(?<message>.+)/
      # time_format '%Y/%m/%d %H:%M:%S'
      format with_extra_fields
      base_format /^\[[^ ]* (?<time>[^\]]*)\] \[(?<level>[^\]]*)\](?: \[pid (?<pid>[^\]]*)\])? \[client (?<client>[^\]]*)\] (?<message>.*)$/
      time_format %d/%b/%Y:%H:%M:%S %z
      extra_fields { "log_type": "error" }
  </pattern>
</match>

<match parsed.apache.piro.**>
  type rewrite_tag_filter
  <rule>
  key     log_type
  pattern ^access$
  tag     piro.apache.access
  </rule>
  <rule>
  key     log_type
  pattern ^error$
  tag     piro.apache.error
  </rule>
</match>

<match piro.apache.access>
    type elasticsearch
    logstash_format true
    logstash_prefix piro.apache-access
    include_tag_key true
    tag_key @log_name
    hosts localhost:9200
    buffer_type memory
    num_threads 1
    flush_interval 60
    retry_wait 1.0
    retry_limit 17
    user elastic
    password <elasticsearch password>
</match>

<match piro.apache.error>
    type elasticsearch
    logstash_format true
    logstash_prefix piro.apache-error
    include_tag_key true
    tag_key @log_name
    hosts localhost:9200
    buffer_type memory
    num_threads 1
    flush_interval 60
    retry_wait 1.0
    retry_limit 17
    user elastic
    password <elasticsearch password>
</match>

4.send log to fluentd server

4.1 RTX1200 & NAS

Set from the browser

4.2 apache

Install fluentd(td-agent) to send apache logs

Installation refers to 1.1

edit td-agent.conf * td-agent.conf

td-agent.conf (send server)
## Input
<source>
  @type tail
  path /var/log/httpd/access_log 
  format apache
    tag apache.access
</source>
<source>
  @type tail
  path /var/log/httpd/error_log 
  format apache
    tag apache.error
</source>
<source>
  @type tail
  path /var/log/httpd/ssl_access_log 
  format apache
    tag apache.access
</source>
<source>
  @type tail
  path /var/log/httpd/ssl_error_log 
  format apache
    tag apache.error
</source>

## Output
<match apache.access>
   @type forward
  send_timeout 60s
  <server>
    host <server ip>
    port <port>
  </server>
</match>
<match apache.error>
   @type forward
  send_timeout 60s
  <server>
    host <server ip>
    port <port>
  </server>
</match>

5.kibana access from the browser

browser access this ip

http://<server ip>:5601

basic auth

plesse input this

ID:elastic
Password:<elastic password>

create index patttern

please create index patterns from the browser
examples:rtx1200-*

confirm discovery

please confirm discovery from the browser

Watcher setting(Alerting on Cluster and Index Events | X-Pack for the Elastic Stack [5.4] | Elastic)

Watcher is one of the functions of x-pack and provides alert function.

seeting from kibana on the browser.

example setting(send to Chatwork)

{
  "trigger": {
    "schedule": {
      "interval": "1m"
    }
  },
  "input": {
    "search": {
      "request": {
        "search_type": "query_then_fetch",
        "indices": [
          "rtx1200-tunnel-*"
        ],
        "types": [],
        "body": {
          "query": {
            "range": {
              "@timestamp": {
                "gte": "now-3m"
              }
            }
          }
        }
      }
    }
  },
  "condition": {
    "compare": {
      "ctx.payload.hits.total": {
        "gte": 3
      }
    }
  },
  "actions": {
    "send_chat": {
      "webhook": {
        "scheme": "https",
        "host": "api.chatwork.com",
        "port": 443,
        "method": "post",
        "path": "/v2/rooms/<room id>/messages",
        "params": {
          "body": "[info][title]VPN Log[/title]type:{{ctx.payload.hits.hits.2._source.log_type}},src-ip:{{ctx.payload.hits.hits.2._source.src_ip}}:{{ctx.payload.hits.hits.2._source.@timestamp}}\ntype:{{ctx.payload.hits.hits.1._source.log_type}},src-ip:{{ctx.payload.hits.hits.1._source.src_ip}}:{{ctx.payload.hits.hits.1._source.@timestamp}}\ntype:{{ctx.payload.hits.hits.0._source.log_type}},src-ip:{{ctx.payload.hits.hits.0._source.src_ip}}:{{ctx.payload.hits.hits.0._source.@timestamp}}[/info]"
        },
        "headers": {
          "X-ChatWorkToken": "<ChatWorkToken>"
        }
      }
    }
  }
}

6.Management Tools

cerebro(GitHub - lmenezes/cerebro)

cerebro can work with easticsearch and manipulate the created index with the GUI.

$ wget https://github.com/lmenezes/cerebro/releases/download/v0.7.2/cerebro-0.7.2.zip
$ unzip cerebro-*.zip
$ cd cerebro-*
$ bin/cerebro

please your browser access localhost:9000

curator(Curator Reference [5.4] | Elastic)

curator can work with elasticsearch to close and delete index existing in elasticsearch.

Step 1 install

  • pip
$ pip install elasticsearch-curator
$ rpm --import https://packages.elastic.co/GPG-KEY-elasticsearch
$ yum install elasticsearch-curator
$ rpm -ivh https://packages.elastic.co/curator/5/centos/7/Packages/elasticsearch-curator-5.4.1-1.x86_64.rpm

Step 2 create curator.yml and action_file

create curator.yml in ~/.curator

  • curator.yml
client:
  hosts:
    - localhost
  port: 9200
  url_prefix:
  use_ssl: False
  certificate:
  client_cert:
  client_key:
  ssl_no_validate: False
  http_auth: elastic:<elasticsearch password>
# if x-pack is installed, set "http_auth: elastic:changeme"
  timeout: 30
  master_only: False

logging:
  loglevel: INFO
  logfile:
  logformat: default
  blacklist: ['elasticsearch', 'urllib3']

create action_file named delete_indices

  • delete_indices
actions:
  1:
    action: delete_indices
    description: >-
      (custommessage)Delete indices older than 5 days (based on index name), for .monitoring-es-
      prefixed indices. Ignore the error if the filter does not result in an
      actionable list of indices (ignore_empty_list) and exit cleanly.(custom message)
    options:
      ignore_empty_list: True
      timeout_override:
      continue_if_exception: False
      disable_action: False
    filters:
    - filtertype: pattern
      kind: prefix
      value: rtx1200-
      exclude:
    - filtertype: age
      source: name
      direction: older
      timestring: '%Y.%m.%d'
      unit: days
      unit_count: 5
      exclude:
  2:
    action: close
    description: >-
      (custom message)Close indices older than 4 days (based on index name), for .monitoring-es-
      prefixed indices.(custom message)
    options:
      ignore_empty_list: True
      delete_aliases: False
      timeout_override:
      continue_if_exception: False
      disable_action: False
    filters:
    - filtertype: pattern
      kind: prefix
      value: rtx1200-
      exclude:
    - filtertype: age
      source: name
      direction: older
      timestring: '%Y.%m.%d'
      unit: days
      unit_count: 4
      exclude:
  3:
    action: delete_indices
    description: >-
      (custommessage)Delete indices older than 5 days (based on index name), for .monitoring-es-
      prefixed indices. Ignore the error if the filter does not result in an
      actionable list of indices (ignore_empty_list) and exit cleanly.(custom message)
    options:
      ignore_empty_list: True
      timeout_override:
      continue_if_exception: False
      disable_action: False
    filters:
    - filtertype: pattern
      kind: prefix
      value: apache
      exclude:
    - filtertype: age
      source: name
      direction: older
      timestring: '%Y.%m.%d'
      unit: days
      unit_count: 5
      exclude:
  4:
    action: close
    description: >-
      (custom message)Close indices older than 4 days (based on index name), for .monitoring-es-
      prefixed indices.(custom message)
    options:
      ignore_empty_list: True
      delete_aliases: False
      timeout_override:
      continue_if_exception: False
      disable_action: False
    filters:
    - filtertype: pattern
      kind: prefix
      value: apache
      exclude:
    - filtertype: age
      source: name
      direction: older
      timestring: '%Y.%m.%d'
      unit: days
      unit_count: 4
      exclude:

  5:
    action: delete_indices
    description: >-
      (custommessage)Delete indices older than 5 days (based on index name), for .monitoring-es-
      prefixed indices. Ignore the error if the filter does not result in an
      actionable list of indices (ignore_empty_list) and exit cleanly.(custom message)
    options:
      ignore_empty_list: True
      timeout_override:
      continue_if_exception: False
      disable_action: False
    filters:
    - filtertype: pattern
      kind: prefix
      value: .
      exclude:
    - filtertype: age
      source: name
      direction: older
      timestring: '%Y.%m.%d'
      unit: days
      unit_count: 5
      exclude:
  6:
    action: close
    description: >-
      (custom message)Close indices older than 4 days (based on index name), for .monitoring-es-
      prefixed indices.(custom message)
    options:
      ignore_empty_list: True
      delete_aliases: False
      timeout_override:
      continue_if_exception: False
      disable_action: False
    filters:
    - filtertype: pattern
      kind: prefix
      value: .
      exclude:
    - filtertype: age
      source: name
      direction: older
      timestring: '%Y.%m.%d'
      unit: days
      unit_count: 4
      exclude:
7:
    action: delete_indices
    description: >-
      (custommessage)Delete indices older than 5 days (based on index name), for .monitoring-es-
      prefixed indices. Ignore the error if the filter does not result in an
      actionable list of indices (ignore_empty_list) and exit cleanly.(custom message)
    options:
      ignore_empty_list: True
      timeout_override:
      continue_if_exception: False
      disable_action: False
    filters:
    - filtertype: pattern
      kind: prefix
      value: myhome-nas
      exclude:
    - filtertype: age
      source: name
      direction: older
      timestring: '%Y.%m.%d'
      unit: days
      unit_count: 5
      exclude:
  8:
    action: close
    description: >-
      (custom message)Close indices older than 4 days (based on index name), for .monitoring-es-
      prefixed indices.(custom message)
    options:
      ignore_empty_list: True
      delete_aliases: False
      timeout_override:
      continue_if_exception: False
      disable_action: False
    filters:
    - filtertype: pattern
      kind: prefix
      value: myhome-nas
      exclude:
    - filtertype: age
      source: name
      direction: older
      timestring: '%Y.%m.%d'
      unit: days
      unit_count: 4
      exclude:

Step3 Run curator

run once

$ curator ~/.curator/delete_indices

run regularly

$ crontab -e

example cron

00 02 * * * curator ~/.curator/delete_indices

HSTSに時間を溶かしたお話

先日開発をしていて,http/httpsが混ざった状態で開発を行っていると,
強制的にhttpsにリダイレクトされる現象に遭遇し.
かなりの時間を消費してしまった.

まず,頭の中に浮かんだのはApacheの設定でリダイレクトしてる可能性.
しかし,htaccessを見てもそのような記述は無いし,
confでリダイレクトしてそうな雰囲気もない.
/var/logを見たところ,それらしい記述があるわけでもないため
サーバーサイドでは無いだろうという結論に至りました.

そして次に考えられたのが,クライアント側の問題だということでした.
クライアント側という点は正解だったのですが,検証方法がまずかったので,
上手く検証することができず,時間を浪費しました.

私が行った検証方法としては,ブラウザを変えるということでした.
私のメインブラウザはFirefoxなので,Chromeに変えることで解決するだろうと思いました.
しかし,Chromeに変えても同じ現象が起きてしまったので,混乱を招きました.
やはりサーバーサイドの問題なのかもしれないと思い,
更に深く調査して(何も問題はない),時間を費やしました.
なぜ私がブラウザとしてFirefoxChromeしか考えられなかったかというと,
普段Debianを使っていて,FirefoxChromeしか入っていないからでした.
その時使っていたのはMacだったのでSafariもあり,Safariで検証すると,
原因を突き止める事ができました.プライバシーモードも有効な手段です.
原因はHSTS(HTTP Strict Transport Security)だったわけですね.
解決するのも大変でして,有効期限を0にして,アクセスし直し,
httpでアクセスできる事を確認してから,https化しなければなりませんでした.
問題としてはどこでこの地雷を踏んでしまったのかがわからないということでした.
私の場合は開発中だったということもあり,ある程度察しがついていたので,
地雷元の探索は少し楽でした.
httpアクセスするためにキャッシュを削除したり,サイトデータを削除したり,
履歴を削除したり,Cookieを削除したり,
削除できるものは削除しようって対策が最も楽な?手段ですね.

対策方法は次を参考にしました.
qiita.com

まあ,私自身の検証力の低さにより苦労したわけですが,
Web系開発の難しさを感じました.

HSTSについて悪いように書いてあるように感じるかもしれませんが,
httpsの方が基本的に安全なこともあり,常時httpsがベーシックになるべきだと思いますが,
開発に対して,こういった影響を与えてしまうので少し困りものです.
開発環境も常にSSL通信するように構築すれば,
こういった問題を回避できるのかもしれませんが…
もちろん私の自宅サーバーは常時SSL通信をリクエストするようにしてありますので,
立場的にはHSTS完全否定派ではないです.

この問題には非常に精神を疲弊させられました.

卒業論文聴講会に参加してきました

おはようございます。
本日は愛媛大学情報工学科の卒業論文発表会がありまして、
8:30〜19:00の長丁場でした。

私は3回生なのですが、来年のために学部3回生は全員集められて、
誰に発表しているのかわからない発表を聞くだけというものでした。

発表風景はこんな感じ。

テーマとしては学部3回生でもある程度出来る人なら、
個人で2ヶ月あれば十分達成出来そうな内容が半分以上に感じました。
テーマとしても、新規性の強い内容はほぼなかったので、
どこかしらで聞いたことがあるような内容を少し編集しましたって感じのテーマが多かったですね。

タイムスケジュールを考えると、まあ当然なのかも分かりませんが、
お昼ご飯の時間が確保されてなくて、非常に悲しいです。

毎回、論文の体裁が〜から始まり、じゃあ最後に質問するねって教授が居て、なんだか楽しかったです。
まあ来年度の自分には被弾しないように頑張ってという感じです。

今日は非常に時間の価値が低い日であったように感じます。
時給で表すと650円ぐらい?

来年度の私としては、卒論の前に院試という重要な関門があるので、
とりあえずはそちらに向けて勉強をしていきたいと思います。
卒論のテーマとしては機械学習とハードウェアの組み合わせをしたいと思っていますが、
RasPi3+tensorflowで画像認識を実装したなんて、 Qiitaに掲載されていそうな卒論は避けたいと思う所存です。

Google Colaboratoryを使った GPU学習環境の実験

今回はGoogle Colaboratoryを使って、
DeepLearningのGPU学習環境が出来るとtwitterで見たので、実験しました。

とりあえず単純にMNISTのCNNやります。
提供されるマシンスペックは次の通りらしいです。

n1-highmem-2 instance
2vCPU @ 2.2GHz
13GB RAM
33GB Free Space
idle cut-off 90 minutes
maximum 12 hours

stackoverflow.com

さあ、始めましょう。
はじめに新規ノートブックの作成を行います。
ノートブックを新規作成よりPython3の新しいノートブックを選びます。

次にランタイムよりランタイムのタイプを変更、ノートブックの設定を開き、
ハードウェアアクセラレータにGPUを選択し、保存します。

新しくセルを作り、下記を入力し、実行する。

import tensorflow as tf
tf.test.gpu_device_name()

下記が出力されれば、GPUアサインされています。

'/device:GPU:0'

CPU/GPUのパフォーマンスを比較してみます。

import tensorflow as tf
import timeit

# See https://www.tensorflow.org/tutorials/using_gpu#allowing_gpu_memory_growth
config = tf.ConfigProto()
config.gpu_options.allow_growth = True

with tf.device('/cpu:0'):
  random_image_cpu = tf.random_normal((100, 100, 100, 3))
  net_cpu = tf.layers.conv2d(random_image_cpu, 32, 7)
  net_cpu = tf.reduce_sum(net_cpu)

with tf.device('/gpu:0'):
  random_image_gpu = tf.random_normal((100, 100, 100, 3))
  net_gpu = tf.layers.conv2d(random_image_gpu, 32, 7)
  net_gpu = tf.reduce_sum(net_gpu)

sess = tf.Session(config=config)

# Test execution once to detect errors early.
try:
  sess.run(tf.global_variables_initializer())
except tf.errors.InvalidArgumentError:
  print(
      '\n\nThis error most likely means that this notebook is not '
      'configured to use a GPU.  Change this in Notebook Settings via the '
      'command palette (cmd/ctrl-shift-P) or the Edit menu.\n\n')
  raise

def cpu():
  sess.run(net_cpu)

def gpu():
  sess.run(net_gpu)

# Runs the op several times.
print('Time (s) to convolve 32x7x7x3 filter over random 100x100x100x3 images '
      '(batch x height x width x channel). Sum of ten runs.')
print('CPU (s):')
cpu_time = timeit.timeit('cpu()', number=10, setup="from __main__ import cpu")
print(cpu_time)
print('GPU (s):')
gpu_time = timeit.timeit('gpu()', number=10, setup="from __main__ import gpu")
print(gpu_time)
print('GPU speedup over CPU: {}x'.format(int(cpu_time/gpu_time)))

sess.close()

下記のような出力が得られると思います。

Time (s) to convolve 32x7x7x3 filter over random 100x100x100x3 images (batch x height x width x channel). Sum of ten runs.
CPU (s):
8.584801190000007
GPU (s):
0.8974968620000254
GPU speedup over CPU: 9x

では、kerasの実行環境を用意しましょう。

!pip install -q keras
import keras

下記の出力が得られる。

Using TensorFlow backend.

ここからが本題です。
データセットの準備を行います。

from keras.datasets import mnist
mnist.load_data()

次に学習を行います。

from __future__ import print_function
import keras
from keras.datasets import mnist
from keras.models import Sequential
from keras.layers import Dense, Dropout
from keras.optimizers import RMSprop
	
batch_size = 128
num_classes = 10
epochs = 20
	
# the data, shuffled and split between train and test sets
(x_train, y_train), (x_test, y_test) = mnist.load_data()
	
x_train = x_train.reshape(60000, 784)
x_test = x_test.reshape(10000, 784)
x_train = x_train.astype('float32')
x_test = x_test.astype('float32')
x_train /= 255
x_test /= 255
print(x_train.shape[0], 'train samples')
print(x_test.shape[0], 'test samples')
	
# convert class vectors to binary class matrices
y_train = keras.utils.to_categorical(y_train, num_classes)
y_test = keras.utils.to_categorical(y_test, num_classes)
	
model = Sequential()
model.add(Dense(512, activation='relu', input_shape=(784,)))
model.add(Dropout(0.2))
model.add(Dense(512, activation='relu'))
model.add(Dropout(0.2))
model.add(Dense(num_classes, activation='softmax'))
	
model.summary()
	
model.compile(loss='categorical_crossentropy',
optimizer=RMSprop(),
metrics=['accuracy'])
	
history = model.fit(x_train, y_train,
batch_size=batch_size,
epochs=epochs,
verbose=1,
validation_data=(x_test, y_test))
score = model.evaluate(x_test, y_test, verbose=0)
print('Test loss:', score[0])
print('Test accuracy:', score[1])

問題なく実行されれば、以下のような出力が得られるでしょう。

60000 train samples
10000 test samples
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
dense_1 (Dense)              (None, 512)               401920    
_________________________________________________________________
dropout_1 (Dropout)          (None, 512)               0         
_________________________________________________________________
dense_2 (Dense)              (None, 512)               262656    
_________________________________________________________________
dropout_2 (Dropout)          (None, 512)               0         
_________________________________________________________________
dense_3 (Dense)              (None, 10)                5130      
=================================================================
Total params: 669,706
Trainable params: 669,706
Non-trainable params: 0
_________________________________________________________________
Train on 60000 samples, validate on 10000 samples
Epoch 1/20
60000/60000 [==============================] - 3s 53us/step - loss: 0.2428 - acc: 0.9256 - val_loss: 0.1074 - val_acc: 0.9653
Epoch 2/20
27392/60000 [============>.................] - ETA: 1s - loss: 0.1097 - acc: 0.9663

60000/60000 [==============================] - 3s 49us/step - loss: 0.1041 - acc: 0.9685 - val_loss: 0.0861 - val_acc: 0.9745
Epoch 3/20
60000/60000 [==============================] - 3s 48us/step - loss: 0.0753 - acc: 0.9771 - val_loss: 0.0678 - val_acc: 0.9805
Epoch 4/20
60000/60000 [==============================] - 3s 48us/step - loss: 0.0586 - acc: 0.9816 - val_loss: 0.0747 - val_acc: 0.9800
Epoch 5/20
60000/60000 [==============================] - 3s 49us/step - loss: 0.0490 - acc: 0.9846 - val_loss: 0.0684 - val_acc: 0.9816
Epoch 6/20
60000/60000 [==============================] - 3s 49us/step - loss: 0.0428 - acc: 0.9875 - val_loss: 0.0697 - val_acc: 0.9808
Epoch 7/20
 7040/60000 [==>...........................] - ETA: 2s - loss: 0.0356 - acc: 0.9895

60000/60000 [==============================] - 3s 48us/step - loss: 0.0390 - acc: 0.9887 - val_loss: 0.0754 - val_acc: 0.9826
Epoch 8/20
60000/60000 [==============================] - 3s 49us/step - loss: 0.0345 - acc: 0.9895 - val_loss: 0.0770 - val_acc: 0.9844
Epoch 9/20
60000/60000 [==============================] - 3s 48us/step - loss: 0.0298 - acc: 0.9911 - val_loss: 0.0807 - val_acc: 0.9835
Epoch 10/20
60000/60000 [==============================] - 3s 49us/step - loss: 0.0275 - acc: 0.9921 - val_loss: 0.1040 - val_acc: 0.9800
Epoch 11/20
60000/60000 [==============================] - 3s 48us/step - loss: 0.0284 - acc: 0.9921 - val_loss: 0.0987 - val_acc: 0.9808
Epoch 12/20
 3712/60000 [>.............................] - ETA: 2s - loss: 0.0217 - acc: 0.9925

60000/60000 [==============================] - 3s 48us/step - loss: 0.0225 - acc: 0.9936 - val_loss: 0.0959 - val_acc: 0.9829
Epoch 13/20
60000/60000 [==============================] - 3s 49us/step - loss: 0.0231 - acc: 0.9935 - val_loss: 0.0934 - val_acc: 0.9834
Epoch 14/20
60000/60000 [==============================] - 3s 49us/step - loss: 0.0225 - acc: 0.9938 - val_loss: 0.0895 - val_acc: 0.9842
Epoch 15/20
60000/60000 [==============================] - 3s 49us/step - loss: 0.0211 - acc: 0.9939 - val_loss: 0.1082 - val_acc: 0.9833
Epoch 16/20
60000/60000 [==============================] - 3s 48us/step - loss: 0.0202 - acc: 0.9946 - val_loss: 0.1097 - val_acc: 0.9832
Epoch 17/20
 3584/60000 [>.............................] - ETA: 2s - loss: 0.0216 - acc: 0.9953

60000/60000 [==============================] - 3s 49us/step - loss: 0.0187 - acc: 0.9951 - val_loss: 0.1067 - val_acc: 0.9831
Epoch 18/20
60000/60000 [==============================] - 3s 49us/step - loss: 0.0210 - acc: 0.9949 - val_loss: 0.1048 - val_acc: 0.9832
Epoch 19/20
60000/60000 [==============================] - 3s 49us/step - loss: 0.0187 - acc: 0.9952 - val_loss: 0.0997 - val_acc: 0.9852
Epoch 20/20
60000/60000 [==============================] - 3s 48us/step - loss: 0.0179 - acc: 0.9954 - val_loss: 0.1143 - val_acc: 0.9842
Test loss: 0.1142890711386806
Test accuracy: 0.9842

これで終了なのですが、Google Colaboratory非常に便利ですね。
無料だし、セットアップする必要が無いので、初学者のスタートアップや
ハンズオンには非常に使いやすいものとなっています。

NextCloudのストレージ移動を行いました。

以前よりストレージを移動させなければならなかったのですが、
そこまで大容量に使用する事がなかったため、行っておりませんでした。
今回NextCloudがメジャーアップデートを行ったので、この機に乗じて
ストレージの移動を行いました。
ついでにmemcachedの設定も行いました。

まずはストレージ移動について
メンテナンスもをオンにして、現状のストレージデータを新規ストレージにコピーして、
所有権を調整し、configとmysqlに新規ストレージの場所を伝えて、
メンテナンスモードをオフして終わりです。

$ sudo -u www-data php /path/to/nextcloud/occ maintenance:mode --on
$ cp /path/to/data /new/path/to/data
$ chown -R www-data:www-data /new/path/to/data
$ nano /path/to/nextcloud/config/config.php
       'datadirectory' => '/new/path/to/data',
$ mysqldump -u<rootuser> -p > /path/to/dbdump/dump.sql
$ mysql -u<rootuser> -p
> use <nextclouddb>;
> update oc_storages set id='local::/new/path/to/data/' where id='local::/path/to/data/'; //take care about backslash at the end of path!!
> quit;
$ sudo -u www-data php /path/to/nextcloud/occ maintenance:mode --off

無事に移動が完了したら、旧データとdump.sqlを削除します。

$ rm -R /path/to/data
$ rm /path/to/dbdump/dump.sql


おまけのmemcached設定。
私はnginx+php7.0-fpm php7.0 on Debian9 で構成しているので、
インストールしたのはphp-apcuのみ。

$ sudo apt install php-apcu
$ sudo vi /var/www/html/nextcloud/config/config.php //以下を追記
‘memcache.local’ => ‘\OC\Memcache\APCu’,

正しく設定されていれば、
nextcloudの管理画面のチェックでmemcachedでのメッセージはなくなるでしょう。

私達の時間とアルバイト

私達の時間の価値を考える

私はお金が足りないので,アルバイトをしている.
大学生でアルバイトをしている人は少なくないのではないだろうか?
その中で自分の1時間をいくらで提供するか,考えたことはあるだろうか?
私は常に考えている.

アルバイトに何を求めるか

私は色々なアルバイトを経験してきた.
定番の塾講師やコンビニバイトからパチンコ店店員も経験した.
基本的には時給と内容,働く時間帯を重視している.
2016年の年末(1週間)は1日20時間ぐらい働いていた.
あのときは頑張ったと思う.1週間で16万ぐらい稼いだ.
現在はWEB系企業のバックエンドエンジニアとしてアルバイトしている.
時給は900円で,交通費が別途出る環境である.
その中で以下の記事を読んだ.
shopetan.hatenablog.com
実際,地方民からするとエンジニアでも学生ならば,雇口が少なく,
あっても時給が1000円に満たない事が多い.
確かに学生の技術力にばらつきは多く(特に地方大学),
採用する企業からすると博打になってしまうのかもしれない.
しかし,ある程度の技術力を持っている学生は存在するので,
学生の時給こそ,一律の時給ではなく,コミットメントに応じたものに
してもらいたいと思う.
学生からすると,成長する場でもあり,生活費を稼ぐ場でもあるのだから,
もう少し評価方法を考えてもらいたい.

最後に

もしアルバイト先の方が見たならば,私は時給上げてほしいと思っています.
現状のままだと,時給が良いところが見つかると移りますよ.

私の考える大学について

まずは現状

現在私は大学3年生であり、この時期となると希望する研究室を決めなくてはいけない。
もちろん、自分の興味のある分野に行きたいし、
出来る限り規模(内容、リソースなど)の大きい研究をしたい気持ちもある。
まず、自分の興味のある分野について考え直してみる。
今考えられるものとすると、機械学習FPGAかなと思っている。
ORというよりANDでしたい分野なので、ハード系の研究室に行くべきかと思っている。
もう一つの出来る限り規模の大きい研究をしたいと思った時に、
自分の行きたい分野の研究室がそれを可能とするか調べなければならない。
しかし、ここで問題が起こった。、研究室について(主に論文と科研費など)調べていくと、
段々思うところが出てきたため、思いを綴っているわけである。

論文や研究費について

調査をしているうちに、ここ数年で論文を書いていない教授が居るという事が
わかってきた。また、企業とコラボしてます、委員会に参加してますなどの情報を
表に出して、自分が最近こういう論文を書きましたという情報が表に出ていない
研究室もあった。科研費についても調べて見たのだが、多くの研究室が現在継続中の
研究が無い状態だった。そういう研究室はどうやって研究費用を回収しているのだろうか?
年々、国から貰える研究費は減っているわけだから、
どうにかして研究費は集めなければならない。
科研費でなければ、それを補うほどの産学連携などを行っているのだろうか?
または国家プロジェクトよりお金をもらっているのだろうか?
大半がそうではないであろう。
学生は4年間大学に通うために、国立大学ならば約250万円はかかる。
それだけの金額を大学に対して、納めているわけだから、それに相当するリターンを
大学は返すべきだと思う。研究室には学費分ぐらいの研究は求めたいと思う。
また、教授に産学連携によって研究費を回収するのはどう思うか聞いた時、
弊大学の教授は産学連携はあまり好みでは無いので行わないと言っていた。
その教授が在籍する研究室では科研費がほとんど与えられていなかったわけだが、
自分の思想を優先するなら、研究費を稼いできてからにしてもらいたい。

弊大学の教授には筑波大学の落合陽一先生の考え方を少しは参考にしてもらいたい。
"「自由と金と責任を与える」というのがコツ。学費以上の研究費が
与えられないラボには絶対にしない、つまり、自分がペイしている金額よりも
リターンが少なくならないようにと決めている。40人いたら最低3000万円の予算は必要だし、
1人あたり100万円以上ラボから与えないと、ペイしていないと思っている"
www.houdoukyoku.jp

金に関する考え方は非常に同意できるのだが、自由と責任に関しては少しどうかと思う。
確かに落合研に入ろうとするレベルなら自由と責任を与えても、結果を残せるだろう。
しかし、弊大学の学生は自由と責任の意味を履き違えている学生が多数居るので、
自由と金と責任を与える事に臆病になるのも頷ける。
お金と自由を渡されて、責任を持って(感じて)行動できる学生は少ないだろう。

では、どうしていくべきなのか

まず、教授には論文を書くということと、科研費や産学連携によって研究規模を上げる。
研究規模を上げる方法は問わない。学内ベンチャーを教授が行うのも良いと思う。
企業とコラボして何かをやるなら、大学機関のままである必要があるのかが不明?なのだが…
学内ベンチャーというシステムではダメだったのであろうか。
研究内容も企業が行うべきことと、大学で行うべきことは見分けるべきだと思う。
研究が盛んに行われていれば、研究室に入りたいと思う学生が増え、
学生が増えることで、レベルが上がっていくだろう。
また、これが出来ない教授にはリストラといったシステムを用意することが必要に感じた。

学生は享受するだけではいけない。
教授が改善しようと行うならば、こちらもそれに対して、
それ相応のリターンをしなければならない。
自分達の大学4年間という有限な時間の使い方をしっかりと考えるべきだろう。
大学は高等学習機関であるわけだから、別に大学に行く義務は発生しない。
しかし、現状はほぼ義務状態になりつつある。
国の政策(大学の学費を免除)の方針を見ると、さらに義務に近いものになりつつある。
わざわざ大学に来て、4年間遊ぶ必要はなく、遊びたいならyoutuberにでもなれば良いのである。
しかし、現状は遊びに来る学生がいるわけだから、現在の弊大学は幼稚園になっている。
私個人的には大学には学習を行う場であって欲しい。
ここでいう学習とは勉強と研究をあわせた意味であり、勉強とは先人が築いたものを学ぶことで、
研究とは先人になることだと考えている。

最後に

今言ったところで、変わらないのは分かっているのだが、
私は大学が早く高等学習機関に戻ることを切に願っている。