From 9a25cfc80b21b8f0d43309c0c3f3fe674a6c1e7f Mon Sep 17 00:00:00 2001
From: Andrew Newdigate <andrew@gitlab.com>
Date: Mon, 29 Oct 2018 13:44:09 +0000
Subject: [PATCH] Fix open-ended params for api_json.log

---
 .../unreleased/53155-structured-logs-params-array.yml  |  5 +++++
 doc/administration/logs.md                             |  2 +-
 .../grape_logging/formatters/lograge_with_timestamp.rb | 10 +++++++++-
 3 files changed, 15 insertions(+), 2 deletions(-)
 create mode 100644 changelogs/unreleased/53155-structured-logs-params-array.yml

diff --git a/changelogs/unreleased/53155-structured-logs-params-array.yml b/changelogs/unreleased/53155-structured-logs-params-array.yml
new file mode 100644
index 00000000000..4d4f68a5c84
--- /dev/null
+++ b/changelogs/unreleased/53155-structured-logs-params-array.yml
@@ -0,0 +1,5 @@
+---
+title: Use key-value pair arrays for API query parameter logging instead of hashes
+merge_request: 22623
+author:
+type: other
diff --git a/doc/administration/logs.md b/doc/administration/logs.md
index 0e41a38b7e2..038e043281c 100644
--- a/doc/administration/logs.md
+++ b/doc/administration/logs.md
@@ -84,7 +84,7 @@ Introduced in GitLab 10.0, this file lives in
 It helps you see requests made directly to the API. For example:
 
 ```json
-{"time":"2017-10-10T12:30:11.579Z","severity":"INFO","duration":16.84,"db":1.57,"view":15.27,"status":200,"method":"POST","path":"/api/v4/internal/allowed","params":{"action":"git-upload-pack","changes":"_any","gl_repository":null,"project":"root/foobar.git","protocol":"ssh","env":"{}","key_id":"[FILTERED]","secret_token":"[FILTERED]"},"host":"127.0.0.1","ip":"127.0.0.1","ua":"Ruby"}
+{"time":"2018-10-29T12:49:42.123Z","severity":"INFO","duration":709.08,"db":14.59,"view":694.49,"status":200,"method":"GET","path":"/api/v4/projects","params":[{"key":"action","value":"git-upload-pack"},{"key":"changes","value":"_any"},{"key":"key_id","value":"secret"},{"key":"secret_token","value":"[FILTERED]"}],"host":"localhost","ip":"::1","ua":"Ruby","route":"/api/:version/projects","user_id":1,"username":"root","queue_duration":100.31,"gitaly_calls":30}
 ```
 
 This entry above shows an access to an internal endpoint to check whether an
diff --git a/lib/gitlab/grape_logging/formatters/lograge_with_timestamp.rb b/lib/gitlab/grape_logging/formatters/lograge_with_timestamp.rb
index 0014ce2689b..41004408dec 100644
--- a/lib/gitlab/grape_logging/formatters/lograge_with_timestamp.rb
+++ b/lib/gitlab/grape_logging/formatters/lograge_with_timestamp.rb
@@ -6,7 +6,7 @@ module Gitlab
 
         def call(severity, datetime, _, data)
           time = data.delete :time
-          data[:params] = utf8_encode_values(data[:params]) if data.has_key?(:params)
+          data[:params] = process_params(data)
 
           attributes = {
             time: datetime.utc.iso8601(3),
@@ -20,6 +20,14 @@ module Gitlab
 
         private
 
+        def process_params(data)
+          return [] unless data.has_key?(:params)
+
+          data[:params]
+            .each_pair
+            .map { |k, v| { key: k, value: utf8_encode_values(v) } }
+        end
+
         def utf8_encode_values(data)
           case data
           when Hash
-- 
2.30.9