diff --git a/ansible/roles/common/tasks/config.yml b/ansible/roles/common/tasks/config.yml index 8b1cad464b..c26166cfa3 100644 --- a/ansible/roles/common/tasks/config.yml +++ b/ansible/roles/common/tasks/config.yml @@ -26,6 +26,7 @@ - { name: "elasticsearch", enabled: "{{ enable_central_logging }}" } - { name: "global", enabled: "yes" } - { name: "haproxy", enabled: "{{ enable_haproxy }}" } + - { name: "horizon", enabled: "{{ enable_horizon }}" } - { name: "keystone", enabled: "{{ enable_keystone }}" } - { name: "mariadb", enabled: "{{ enable_mariadb }}" } - { name: "openstack", enabled: "yes" } diff --git a/ansible/roles/common/templates/heka-horizon.toml.j2 b/ansible/roles/common/templates/heka-horizon.toml.j2 new file mode 100644 index 0000000000..d3d4ac100c --- /dev/null +++ b/ansible/roles/common/templates/heka-horizon.toml.j2 @@ -0,0 +1,13 @@ +[horizon_apache_log_decoder] +type = "SandboxDecoder" +filename = "lua_decoders/os_horizon_apache_log.lua" + [horizon_apache_log_decoder.config] + apache_log_pattern = '%{X-Forwarded-For}i %l %u %t \"%r\" %>s %b %D \"%{Referer}i\" \"%{User-Agent}i\"' + +[horizon_apache_logstreamer_input] +type = "LogstreamerInput" +decoder = "horizon_apache_log_decoder" +log_directory = "/var/log/kolla" +file_match = 'horizon/horizon-apache-(?P.+)-access\.log\.?(?P\d*)$' +priority = ["^Seq"] +differentiator = ["horizon-apache-", "Service"] diff --git a/ansible/roles/common/templates/heka.json.j2 b/ansible/roles/common/templates/heka.json.j2 index 1087c60d0f..94bd31d1e1 100644 --- a/ansible/roles/common/templates/heka.json.j2 +++ b/ansible/roles/common/templates/heka.json.j2 @@ -45,6 +45,13 @@ "owner": "heka", "perm": "0600" }, + { + "source": "{{ container_config_directory }}/heka-horizon.toml", + "dest": "/etc/heka/heka-horizon.toml", + "owner": "heka", + "perm": "0600", + "optional": {{ (not enable_horizon | bool) | string | lower }} + }, {% for swift_service in swift_services %} { "source": "{{ container_config_directory }}/heka-{{ swift_service }}.toml", diff --git a/ansible/roles/horizon/tasks/config.yml b/ansible/roles/horizon/tasks/config.yml index 28ded6d71d..d70d73adf8 100644 --- a/ansible/roles/horizon/tasks/config.yml +++ b/ansible/roles/horizon/tasks/config.yml @@ -21,7 +21,6 @@ with_items: - "horizon" - - name: Copying over local_settings template: src: "local_settings.j2" diff --git a/ansible/roles/horizon/tasks/start.yml b/ansible/roles/horizon/tasks/start.yml index 19d0f87591..b9d6eb14a8 100644 --- a/ansible/roles/horizon/tasks/start.yml +++ b/ansible/roles/horizon/tasks/start.yml @@ -5,5 +5,7 @@ common_options: "{{ docker_common_options }}" image: "{{ horizon_image_full }}" name: "horizon" - volumes: "{{ node_config_directory }}/horizon/:{{ container_config_directory }}/:ro" + volumes: + - "{{ node_config_directory }}/horizon/:{{ container_config_directory }}/:ro" + - "kolla_logs:/var/log/kolla/" when: inventory_hostname in groups['horizon'] diff --git a/ansible/roles/horizon/templates/horizon.conf.j2 b/ansible/roles/horizon/templates/horizon.conf.j2 index 1881978d02..b43b2b843e 100644 --- a/ansible/roles/horizon/templates/horizon.conf.j2 +++ b/ansible/roles/horizon/templates/horizon.conf.j2 @@ -1,11 +1,10 @@ -{% set apache_dir = 'apache2' if kolla_base_distro in ['ubuntu', 'debian'] else 'httpd' %} {% set python_path = '/usr/lib/python2.7/site-packages' if kolla_install_type == 'binary' else '/var/lib/kolla/venv/lib/python2.7/site-packages' %} Listen {{ hostvars[inventory_hostname]['ansible_' + api_interface]['ipv4']['address'] }}:80 LogLevel warn - ErrorLog /var/log/{{ apache_dir }}/horizon.log - CustomLog /var/log/{{ apache_dir }}/horizon-access.log combined + ErrorLog /var/log/kolla/horizon/horizon.log + CustomLog /var/log/kolla/horizon/horizon-access.log combined WSGIScriptReloading On WSGIDaemonProcess horizon-http processes=5 threads=1 user=horizon group=horizon display-name=%{GROUP} python-path={{ python_path }} diff --git a/docker/heka/plugins/decoders/os_horizon_apache_log.lua b/docker/heka/plugins/decoders/os_horizon_apache_log.lua new file mode 100644 index 0000000000..e9421d0aa3 --- /dev/null +++ b/docker/heka/plugins/decoders/os_horizon_apache_log.lua @@ -0,0 +1,72 @@ +-- Copyright 2015 Mirantis, Inc. +-- +-- Licensed under the Apache License, Version 2.0 (the "License"); +-- you may not use this file except in compliance with the License. +-- You may obtain a copy of the License at +-- +-- http://www.apache.org/licenses/LICENSE-2.0 +-- +-- Unless required by applicable law or agreed to in writing, software +-- distributed under the License is distributed on an "AS IS" BASIS, +-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +-- See the License for the specific language governing permissions and +-- limitations under the License. + +local l = require 'lpeg' +l.locale(l) + +local common_log_format = require 'common_log_format' +local patt = require 'os_patterns' +local utils = require 'os_utils' + +local msg = { + Timestamp = nil, + Type = 'log', + Hostname = nil, + Payload = nil, + Pid = nil, + Fields = nil, + Severity = 6, +} + +local severity_label = utils.severity_to_label_map[msg.Severity] + +local apache_log_pattern = read_config("apache_log_pattern") or error( + "apache_log_pattern configuration must be specificed") +local apache_grammar = common_log_format.build_apache_grammar(apache_log_pattern) +local request_grammar = l.Ct(patt.http_request) + +function process_message () + + -- logger is either "horizon-apache-public" or "horizon-apache-admin" + local logger = read_message("Logger") + + local log = read_message("Payload") + + local m + + m = apache_grammar:match(log) + if m then + msg.Logger = 'openstack.horizon' + msg.Payload = log + msg.Timestamp = m.time + + msg.Fields = {} + msg.Fields.http_status = m.status + msg.Fields.http_response_time = m.request_time.value / 1e6 -- us to sec + msg.Fields.programname = logger + msg.Fields.severity_label = severity_label + + local request = m.request + m = request_grammar:match(request) + if m then + msg.Fields.http_method = m.http_method + msg.Fields.http_url = m.http_url + msg.Fields.http_version = m.http_version + end + + return utils.safe_inject_message(msg) + end + + return -1, string.format("Failed to parse %s log: %s", logger, string.sub(log, 1, 64)) +end