mirror of
https://github.com/samsonjs/grape_logging.git
synced 2026-03-25 08:55:47 +00:00
Compare commits
43 commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 9f35f74bd5 | |||
|
|
073a88614b | ||
|
|
df56d571b7 | ||
|
|
3b2ebd5669 | ||
| f9d417f2d6 | |||
| 189e6f0857 | |||
| 48ab8c414b | |||
|
|
a8290d3522 | ||
| d97750a318 | |||
| ffdd1a617c | |||
| 39f6a064f1 | |||
| ed25898685 | |||
| 5a9ef5d801 | |||
| ca80cfef6c | |||
| 08823ae0d1 | |||
| 586dc239dc | |||
| 7e15b97cb4 | |||
| a17c5f52e4 | |||
| dbba26bc2c | |||
| 31d46bc8f8 | |||
| 4fabe1aa37 | |||
| b8452343f0 | |||
| 71c1adf3eb | |||
| a4f6088a17 | |||
| c19b1d3732 | |||
| 362dd0a92e | |||
| 0d738e4e7e | |||
| 9e4fb8266b | |||
| f35dc1e9d6 | |||
| 585cd29a7d | |||
| d8d3f3ca1e | |||
| 16062114b1 | |||
|
|
fe2d196494 | ||
|
|
b94fcb3046 | ||
| f7341032d5 | |||
| 59813dedbc | |||
| 0d70063ae5 | |||
| ce103dad5a | |||
|
|
cc29dc7868 | ||
|
|
01846a40ef | ||
|
|
6e562a2788 | ||
|
|
ea6afd1d0f | ||
|
|
58e7475b64 |
36 changed files with 1102 additions and 375 deletions
36
.github/workflows/ci.yml
vendored
Normal file
36
.github/workflows/ci.yml
vendored
Normal file
|
|
@ -0,0 +1,36 @@
|
||||||
|
name: CI
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [master]
|
||||||
|
pull_request:
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
test:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
ruby-version: ["3.0", "3.1", "3.2", "3.3", "3.4", "4.0"]
|
||||||
|
steps:
|
||||||
|
- name: Checkout code
|
||||||
|
uses: actions/checkout@v6
|
||||||
|
- uses: ruby/setup-ruby@v1
|
||||||
|
with:
|
||||||
|
ruby-version: ${{ matrix.ruby-version }}
|
||||||
|
bundler-cache: true
|
||||||
|
- name: Install dependencies
|
||||||
|
run: bundle install --jobs 4 --retry 3
|
||||||
|
- name: Run tests
|
||||||
|
run: bundle exec rake spec
|
||||||
|
lint:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Checkout code
|
||||||
|
uses: actions/checkout@v6
|
||||||
|
- uses: ruby/setup-ruby@v1
|
||||||
|
with:
|
||||||
|
ruby-version: "4.0"
|
||||||
|
bundler-cache: true
|
||||||
|
- name: Install dependencies
|
||||||
|
run: bundle install
|
||||||
|
- name: Run RuboCop
|
||||||
|
run: bundle exec rake rubocop
|
||||||
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -8,3 +8,4 @@
|
||||||
/spec/reports/
|
/spec/reports/
|
||||||
/tmp/
|
/tmp/
|
||||||
.rspec
|
.rspec
|
||||||
|
.idea/
|
||||||
15
.rubocop.yml
Normal file
15
.rubocop.yml
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
inherit_from: .rubocop_todo.yml
|
||||||
|
|
||||||
|
AllCops:
|
||||||
|
NewCops: enable
|
||||||
|
TargetRubyVersion: 3.0
|
||||||
|
|
||||||
|
Metrics/BlockLength:
|
||||||
|
CountAsOne: [array, hash, heredoc, method_call]
|
||||||
|
|
||||||
|
Metrics/ClassLength:
|
||||||
|
CountAsOne: [array, hash, heredoc, method_call]
|
||||||
|
|
||||||
|
Metrics/MethodLength:
|
||||||
|
CountAsOne: [array, hash, heredoc, method_call]
|
||||||
|
Max: 20
|
||||||
160
.rubocop_todo.yml
Normal file
160
.rubocop_todo.yml
Normal file
|
|
@ -0,0 +1,160 @@
|
||||||
|
# This configuration was generated by
|
||||||
|
# `rubocop --auto-gen-config`
|
||||||
|
# on 2025-07-10 10:25:51 UTC using RuboCop version 1.77.0.
|
||||||
|
# The point is for the user to remove these configuration records
|
||||||
|
# one by one as the offenses are removed from the code base.
|
||||||
|
# Note that changes in the inspected code, or installation of new
|
||||||
|
# versions of RuboCop, may require this file to be generated again.
|
||||||
|
|
||||||
|
# Offense count: 3
|
||||||
|
# Configuration parameters: EnforcedStyle, AllowedGems, Include.
|
||||||
|
# SupportedStyles: Gemfile, gems.rb, gemspec
|
||||||
|
# Include: **/*.gemspec, **/Gemfile, **/gems.rb
|
||||||
|
Gemspec/DevelopmentDependencies:
|
||||||
|
Exclude:
|
||||||
|
- "grape_logging.gemspec"
|
||||||
|
|
||||||
|
# Offense count: 1
|
||||||
|
# This cop supports safe autocorrection (--autocorrect).
|
||||||
|
# Configuration parameters: Severity, Include.
|
||||||
|
# Include: **/*.gemspec
|
||||||
|
Gemspec/RequireMFA:
|
||||||
|
Exclude:
|
||||||
|
- "grape_logging.gemspec"
|
||||||
|
|
||||||
|
# Offense count: 1
|
||||||
|
# Configuration parameters: Severity, Include.
|
||||||
|
# Include: **/*.gemspec
|
||||||
|
Gemspec/RequiredRubyVersion:
|
||||||
|
Exclude:
|
||||||
|
- "grape_logging.gemspec"
|
||||||
|
|
||||||
|
# Offense count: 1
|
||||||
|
# Configuration parameters: IgnoreLiteralBranches, IgnoreConstantBranches, IgnoreDuplicateElseBranch.
|
||||||
|
Lint/DuplicateBranch:
|
||||||
|
Exclude:
|
||||||
|
- "lib/grape_logging/util/parameter_filter.rb"
|
||||||
|
|
||||||
|
# Offense count: 1
|
||||||
|
# Configuration parameters: AllowedParentClasses.
|
||||||
|
Lint/MissingSuper:
|
||||||
|
Exclude:
|
||||||
|
- "lib/grape_logging/loggers/filter_parameters.rb"
|
||||||
|
|
||||||
|
# Offense count: 3
|
||||||
|
# Configuration parameters: AllowedMethods, AllowedPatterns, CountRepeatedAttributes.
|
||||||
|
Metrics/AbcSize:
|
||||||
|
Max: 38
|
||||||
|
|
||||||
|
# Offense count: 8
|
||||||
|
# Configuration parameters: CountComments, CountAsOne, AllowedMethods, AllowedPatterns.
|
||||||
|
# AllowedMethods: refine
|
||||||
|
Metrics/BlockLength:
|
||||||
|
Max: 90
|
||||||
|
|
||||||
|
# Offense count: 3
|
||||||
|
# Configuration parameters: AllowedMethods, AllowedPatterns.
|
||||||
|
Metrics/CyclomaticComplexity:
|
||||||
|
Max: 18
|
||||||
|
|
||||||
|
# Offense count: 2
|
||||||
|
# Configuration parameters: AllowedMethods, AllowedPatterns.
|
||||||
|
Metrics/PerceivedComplexity:
|
||||||
|
Max: 19
|
||||||
|
|
||||||
|
# Offense count: 2
|
||||||
|
# Configuration parameters: EnforcedStyle, CheckMethodNames, CheckSymbols, AllowedIdentifiers, AllowedPatterns.
|
||||||
|
# SupportedStyles: snake_case, normalcase, non_integer
|
||||||
|
# AllowedIdentifiers: TLS1_1, TLS1_2, capture3, iso8601, rfc1123_date, rfc822, rfc2822, rfc3339, x86_64
|
||||||
|
Naming/VariableNumber:
|
||||||
|
Exclude:
|
||||||
|
- "spec/lib/grape_logging/formatters/rails_spec.rb"
|
||||||
|
|
||||||
|
# Offense count: 3
|
||||||
|
# This cop supports unsafe autocorrection (--autocorrect-all).
|
||||||
|
# Configuration parameters: MinBranchesCount.
|
||||||
|
Style/CaseLikeIf:
|
||||||
|
Exclude:
|
||||||
|
- "lib/grape_logging/formatters/default.rb"
|
||||||
|
- "lib/grape_logging/formatters/logstash.rb"
|
||||||
|
- "lib/grape_logging/formatters/rails.rb"
|
||||||
|
|
||||||
|
# Offense count: 17
|
||||||
|
# Configuration parameters: AllowedConstants.
|
||||||
|
Style/Documentation:
|
||||||
|
Enabled: false
|
||||||
|
|
||||||
|
# Offense count: 29
|
||||||
|
# This cop supports unsafe autocorrection (--autocorrect-all).
|
||||||
|
# Configuration parameters: EnforcedStyle.
|
||||||
|
# SupportedStyles: always, always_true, never
|
||||||
|
Style/FrozenStringLiteralComment:
|
||||||
|
Enabled: false
|
||||||
|
|
||||||
|
# Offense count: 1
|
||||||
|
# This cop supports unsafe autocorrection (--autocorrect-all).
|
||||||
|
Style/GlobalStdStream:
|
||||||
|
Exclude:
|
||||||
|
- "lib/grape_logging/reporters/logger_reporter.rb"
|
||||||
|
|
||||||
|
# Offense count: 1
|
||||||
|
# This cop supports unsafe autocorrection (--autocorrect-all).
|
||||||
|
# Configuration parameters: EnforcedStyle.
|
||||||
|
# SupportedStyles: literals, strict
|
||||||
|
Style/MutableConstant:
|
||||||
|
Exclude:
|
||||||
|
- "lib/grape_logging/version.rb"
|
||||||
|
|
||||||
|
# Offense count: 10
|
||||||
|
Style/OpenStructUse:
|
||||||
|
Exclude:
|
||||||
|
- "spec/lib/grape_logging/loggers/client_env_spec.rb"
|
||||||
|
- "spec/lib/grape_logging/loggers/filter_parameters_spec.rb"
|
||||||
|
- "spec/lib/grape_logging/loggers/request_headers_spec.rb"
|
||||||
|
- "spec/lib/grape_logging/loggers/response_spec.rb"
|
||||||
|
|
||||||
|
# Offense count: 3
|
||||||
|
# This cop supports unsafe autocorrection (--autocorrect-all).
|
||||||
|
# Configuration parameters: ConvertCodeThatCanStartToReturnNil, AllowedMethods, MaxChainLength.
|
||||||
|
# AllowedMethods: present?, blank?, presence, try, try!
|
||||||
|
Style/SafeNavigation:
|
||||||
|
Exclude:
|
||||||
|
- "lib/grape_logging/formatters/rails.rb"
|
||||||
|
|
||||||
|
# Offense count: 1
|
||||||
|
# This cop supports unsafe autocorrection (--autocorrect-all).
|
||||||
|
Style/SlicingWithRange:
|
||||||
|
Exclude:
|
||||||
|
- "lib/grape_logging/loggers/request_headers.rb"
|
||||||
|
|
||||||
|
# Offense count: 1
|
||||||
|
# This cop supports unsafe autocorrection (--autocorrect-all).
|
||||||
|
# Configuration parameters: RequireEnglish, EnforcedStyle.
|
||||||
|
# SupportedStyles: use_perl_names, use_english_names, use_builtin_english_names
|
||||||
|
Style/SpecialGlobalVars:
|
||||||
|
Exclude:
|
||||||
|
- "spec/spec_helper.rb"
|
||||||
|
|
||||||
|
# Offense count: 3
|
||||||
|
# This cop supports unsafe autocorrection (--autocorrect-all).
|
||||||
|
# Configuration parameters: Mode.
|
||||||
|
Style/StringConcatenation:
|
||||||
|
Exclude:
|
||||||
|
- "lib/grape_logging/formatters/json.rb"
|
||||||
|
- "lib/grape_logging/formatters/lograge.rb"
|
||||||
|
- "lib/grape_logging/formatters/logstash.rb"
|
||||||
|
|
||||||
|
# Offense count: 1
|
||||||
|
# This cop supports unsafe autocorrection (--autocorrect-all).
|
||||||
|
# Configuration parameters: AllowMethodsWithArguments, AllowedMethods, AllowedPatterns, AllowComments.
|
||||||
|
# AllowedMethods: define_method
|
||||||
|
Style/SymbolProc:
|
||||||
|
Exclude:
|
||||||
|
- "lib/grape_logging/util/parameter_filter.rb"
|
||||||
|
|
||||||
|
# Offense count: 11
|
||||||
|
# This cop supports safe autocorrection (--autocorrect).
|
||||||
|
# Configuration parameters: AllowHeredoc, AllowURI, AllowQualifiedName, URISchemes, IgnoreCopDirectives, AllowedPatterns, SplitStrings.
|
||||||
|
# URISchemes: http, https
|
||||||
|
Layout/LineLength:
|
||||||
|
Max: 203
|
||||||
|
|
@ -1,6 +0,0 @@
|
||||||
language: ruby
|
|
||||||
rvm:
|
|
||||||
- 2.3.1
|
|
||||||
cache: bundler
|
|
||||||
script:
|
|
||||||
- bundle exec rspec
|
|
||||||
225
CHANGELOG.md
Normal file
225
CHANGELOG.md
Normal file
|
|
@ -0,0 +1,225 @@
|
||||||
|
# Changelog
|
||||||
|
|
||||||
|
## [3.0.1] - Unreleased
|
||||||
|
|
||||||
|
### Changed or Fixed or Added
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
- Move dev dependencies to Gemfile
|
||||||
|
- Use zeitwerk to load gem
|
||||||
|
|
||||||
|
[3.0.1]: https://github.com/aserafin/grape_logging/compare/v3.0.0...master
|
||||||
|
|
||||||
|
## [3.0.0] - 2025-08-07
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
- [#93](https://github.com/aserafin/grape_logging/pull/93) RequestLogger middleware to handle Grape 2.4 breaking change - [@devsigner](https://github.com/devsigner) and [@samsonjs](https://github.com/samsonjs).
|
||||||
|
|
||||||
|
[3.0.0]: https://github.com/aserafin/grape_logging/compare/v2.1.1...v3.0.0
|
||||||
|
|
||||||
|
## [2.1.1] - 2025-07-09
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
- [#92](https://github.com/aserafin/grape_logging/pull/92) Handle symbol param keys during filtering - [@samsonjs](https://github.com/samsonjs).
|
||||||
|
|
||||||
|
[2.1.1]: https://github.com/aserafin/grape_logging/compare/v2.1.0...v2.1.1
|
||||||
|
|
||||||
|
## [2.1.0] - 2025-07-09
|
||||||
|
|
||||||
|
### Added
|
||||||
|
- [#91](https://github.com/aserafin/grape_logging/pull/91) Add ActionDispatch request ID to logger arguments hash as `:request_id` - [@samsonjs](https://github.com/samsonjs).
|
||||||
|
|
||||||
|
[2.1.0]: https://github.com/aserafin/grape_logging/compare/v2.0.0...v2.1.0
|
||||||
|
|
||||||
|
## [2.0.0] - 2025-07-09
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
- **BREAKING**: Updated to support Grape 2.1 and Rack 3.1
|
||||||
|
- Minimum supported Ruby version is now 3.0
|
||||||
|
- Replaced Travis CI with GitHub Actions for continuous integration
|
||||||
|
- Updated all README examples to use `insert_before` instead of `use` for proper middleware placement
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
- Fixed LoggerReporter to clone the logger parameter to prevent shared state issues (#77)
|
||||||
|
- Fixed view time precision issue by rounding to 2 decimal places
|
||||||
|
- Fixed invalid byte sequence handling for parameter keys by properly managing string encodings (#54)
|
||||||
|
- Fixed various typos in code comments and spec descriptions (#87)
|
||||||
|
- Fixed specs to work with Ruby 3.4's hash inspect format changes
|
||||||
|
|
||||||
|
### Documentation
|
||||||
|
- Clarified middleware placement requirements in README - must be inserted before Grape::Middleware::Error (#74)
|
||||||
|
- Added gem version badge to README
|
||||||
|
|
||||||
|
[2.0.0]: https://github.com/aserafin/grape_logging/compare/v1.8.4...v2.0.0
|
||||||
|
|
||||||
|
## [1.8.4] - 2021-10-29
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
- Rails 6 compatibility improvements
|
||||||
|
- Various bug fixes and dependency updates
|
||||||
|
|
||||||
|
[1.8.4]: https://github.com/aserafin/grape_logging/compare/v1.8.3...v1.8.4
|
||||||
|
|
||||||
|
## [1.8.3] - 2020-02-27
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
- Performance improvements
|
||||||
|
- Bug fixes for edge cases
|
||||||
|
|
||||||
|
[1.8.3]: https://github.com/aserafin/grape_logging/compare/v1.8.2...v1.8.3
|
||||||
|
|
||||||
|
## [1.8.2] - 2019-10-08
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
- Thread safety improvements
|
||||||
|
- Minor bug fixes
|
||||||
|
|
||||||
|
Note: This version was tagged as "v.1.8.2" (with extra dot)
|
||||||
|
|
||||||
|
[1.8.2]: https://github.com/aserafin/grape_logging/compare/v1.8.1...v.1.8.2
|
||||||
|
|
||||||
|
## [1.8.1] - 2019-08-07
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
- Bug fixes for parameter filtering
|
||||||
|
- Improved error handling
|
||||||
|
|
||||||
|
[1.8.1]: https://github.com/aserafin/grape_logging/compare/v1.8.0...v1.8.1
|
||||||
|
|
||||||
|
## [1.8.0] - 2019-05-30
|
||||||
|
|
||||||
|
### Added
|
||||||
|
- Rails formatter for better Rails integration
|
||||||
|
- Improved Rails instrumentation support
|
||||||
|
|
||||||
|
[1.8.0]: https://github.com/aserafin/grape_logging/compare/v1.7.0...v1.8.0
|
||||||
|
|
||||||
|
## [1.7.0] - 2017-11-09
|
||||||
|
|
||||||
|
### Added
|
||||||
|
- Logstash formatter for ELK stack integration
|
||||||
|
- Enhanced JSON formatting options
|
||||||
|
|
||||||
|
[1.7.0]: https://github.com/aserafin/grape_logging/compare/v1.6.0...v1.7.0
|
||||||
|
|
||||||
|
## [1.6.0] - 2017-07-20
|
||||||
|
|
||||||
|
### Added
|
||||||
|
- MultiIO support for logging to multiple destinations simultaneously
|
||||||
|
- Can now log to both file and STDOUT
|
||||||
|
|
||||||
|
[1.6.0]: https://github.com/aserafin/grape_logging/compare/v1.5.0...v1.6.0
|
||||||
|
|
||||||
|
## [1.5.0] - 2017-06-15
|
||||||
|
|
||||||
|
### Added
|
||||||
|
- Configurable log levels
|
||||||
|
- Better control over logging verbosity
|
||||||
|
|
||||||
|
[1.5.0]: https://github.com/aserafin/grape_logging/compare/v1.4.0...v1.5.0
|
||||||
|
|
||||||
|
## [1.4.0] - 2017-01-12
|
||||||
|
|
||||||
|
### Added
|
||||||
|
- FilterParameters logger for sensitive parameter filtering
|
||||||
|
- Automatic Rails filter_parameters integration when available
|
||||||
|
|
||||||
|
[1.4.0]: https://github.com/aserafin/grape_logging/compare/v1.3.0...v1.4.0
|
||||||
|
|
||||||
|
## [1.3.0] - 2016-12-08
|
||||||
|
|
||||||
|
### Added
|
||||||
|
- RequestHeaders logger for logging HTTP request headers
|
||||||
|
- ClientEnv logger for logging client IP and user agent
|
||||||
|
|
||||||
|
[1.3.0]: https://github.com/aserafin/grape_logging/compare/v1.2.1...v1.3.0
|
||||||
|
|
||||||
|
## [1.2.1] - 2016-04-14
|
||||||
|
|
||||||
|
### Added
|
||||||
|
- JSON formatter for structured logging
|
||||||
|
- Rails instrumentation support via ActiveSupport::Notifications
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
- Parameter handling improvements
|
||||||
|
|
||||||
|
[1.2.1]: https://github.com/aserafin/grape_logging/compare/v1.2.0...v1.2.1
|
||||||
|
|
||||||
|
## [1.2.0] - 2016-01-21
|
||||||
|
|
||||||
|
### Added
|
||||||
|
- Response logger for logging response details
|
||||||
|
- Improved parameter logging
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
- Better integration with Grape middleware stack
|
||||||
|
|
||||||
|
[1.2.0]: https://github.com/aserafin/grape_logging/compare/v1.1.3...v1.2.0
|
||||||
|
|
||||||
|
## [1.1.3] - 2015-12-03
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
- Bug fixes for Grape 0.14 compatibility
|
||||||
|
- Improved error handling
|
||||||
|
|
||||||
|
[1.1.3]: https://github.com/aserafin/grape_logging/compare/v1.1.2...v1.1.3
|
||||||
|
|
||||||
|
## [1.1.2] - 2015-11-19
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
- Performance optimizations
|
||||||
|
- Minor bug fixes
|
||||||
|
|
||||||
|
[1.1.2]: https://github.com/aserafin/grape_logging/compare/v1.1.1...v1.1.2
|
||||||
|
|
||||||
|
## [1.1.1] - 2015-11-12
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
- Critical bug fix for middleware initialization
|
||||||
|
|
||||||
|
Note: This version was tagged as "v.1.1.1" (with extra dot)
|
||||||
|
|
||||||
|
[1.1.1]: https://github.com/aserafin/grape_logging/compare/v1.1.0...v.1.1.1
|
||||||
|
|
||||||
|
## [1.1.0] - 2015-11-09
|
||||||
|
|
||||||
|
### Added
|
||||||
|
- Pluggable logger architecture
|
||||||
|
- Support for custom loggers via include option
|
||||||
|
- Base logger class for extending functionality
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
- Refactored middleware for better extensibility
|
||||||
|
|
||||||
|
[1.1.0]: https://github.com/aserafin/grape_logging/compare/v1.0.3...v1.1.0
|
||||||
|
|
||||||
|
## [1.0.3] - 2015-11-05
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
- Compatibility fixes for different Grape versions
|
||||||
|
- Bug fixes
|
||||||
|
|
||||||
|
[1.0.3]: https://github.com/aserafin/grape_logging/compare/v1.0.2...v1.0.3
|
||||||
|
|
||||||
|
## [1.0.2] - 2015-10-29
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
- Minor bug fixes and improvements
|
||||||
|
|
||||||
|
[1.0.2]: https://github.com/aserafin/grape_logging/compare/v1.0.1...v1.0.2
|
||||||
|
|
||||||
|
## [1.0.1] - 2015-10-22
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
- Initial bug fixes after 1.0 release
|
||||||
|
|
||||||
|
[1.0.1]: https://github.com/aserafin/grape_logging/compare/v1.0...v1.0.1
|
||||||
|
|
||||||
|
## [1.0] - 2015-10-15
|
||||||
|
|
||||||
|
### Added
|
||||||
|
- Initial release
|
||||||
|
- Request logging middleware for Grape APIs
|
||||||
|
- Basic request/response logging
|
||||||
|
- Configurable formatters
|
||||||
|
- Time tracking (total, db, view)
|
||||||
110
CONTRIBUTING.md
Normal file
110
CONTRIBUTING.md
Normal file
|
|
@ -0,0 +1,110 @@
|
||||||
|
# Contributing to grape_logging
|
||||||
|
|
||||||
|
This project is work of many contributors. You're encouraged to submit pull requests, propose features and discuss issues.
|
||||||
|
|
||||||
|
## Fork the Project
|
||||||
|
|
||||||
|
Fork the project on Github and check out your copy.
|
||||||
|
|
||||||
|
```
|
||||||
|
git clone https://github.com/contributor/grape_logging.git
|
||||||
|
cd grape_logging
|
||||||
|
git remote add upstream https://github.com/aserafin/grape_logging.git
|
||||||
|
```
|
||||||
|
|
||||||
|
## Create a Topic Branch
|
||||||
|
|
||||||
|
Make sure your fork is up-to-date and create a topic branch for your feature or bug fix.
|
||||||
|
|
||||||
|
```
|
||||||
|
git checkout master
|
||||||
|
git pull upstream master
|
||||||
|
git checkout -b my-feature-branch
|
||||||
|
```
|
||||||
|
|
||||||
|
## Bundle Install and Test
|
||||||
|
|
||||||
|
Ensure that you can build the project and run tests.
|
||||||
|
|
||||||
|
```
|
||||||
|
bundle install
|
||||||
|
bundle exec rake
|
||||||
|
```
|
||||||
|
|
||||||
|
## Write Tests
|
||||||
|
|
||||||
|
Try to write a test that reproduces the problem you're trying to fix or describes a feature that you want to build. Add to the spec directory.
|
||||||
|
|
||||||
|
## Write Code
|
||||||
|
|
||||||
|
Implement your feature or bug fix.
|
||||||
|
|
||||||
|
Ruby style is enforced with RuboCop. Run `bundle exec rubocop` and fix any style issues highlighted.
|
||||||
|
|
||||||
|
Make sure that `bundle exec rake` completes without errors.
|
||||||
|
|
||||||
|
## Write Documentation
|
||||||
|
|
||||||
|
Document any external behavior in the README.md.
|
||||||
|
|
||||||
|
## Update Changelog
|
||||||
|
|
||||||
|
Add a line to Changelog.md under *Next Release*. Make it look like every other line, including your name and link to your Github account.
|
||||||
|
|
||||||
|
## Commit Changes
|
||||||
|
|
||||||
|
Make sure git knows your name and email address:
|
||||||
|
|
||||||
|
```
|
||||||
|
git config --global user.name "Your Name"
|
||||||
|
git config --global user.email "contributor@example.com"
|
||||||
|
```
|
||||||
|
|
||||||
|
Writing good commit logs is important. A commit log should describe what changed and why.
|
||||||
|
|
||||||
|
```
|
||||||
|
git add ...
|
||||||
|
git commit
|
||||||
|
```
|
||||||
|
|
||||||
|
## Push
|
||||||
|
|
||||||
|
```
|
||||||
|
git push origin my-feature-branch
|
||||||
|
```
|
||||||
|
|
||||||
|
## Make a Pull Request
|
||||||
|
|
||||||
|
Go to https://github.com/contributor/grape_logging and select your feature branch. Click the 'Pull Request' button and fill out the form.
|
||||||
|
|
||||||
|
We'll try to review pull requests within a few days but as this is maintained by a small group of volunteers there is no guarantee that we'll look at it within any time frame, or at all. There's no maintenance guarantee.
|
||||||
|
|
||||||
|
## Discuss and Update
|
||||||
|
|
||||||
|
You may get feedback or requests for changes to your pull request. This is a big part of the submission process so don't be discouraged!
|
||||||
|
|
||||||
|
Some things that will increase the chance that your pull request is accepted:
|
||||||
|
|
||||||
|
- Write tests.
|
||||||
|
- Follow the Ruby style guide.
|
||||||
|
- Write a good commit message.
|
||||||
|
|
||||||
|
If you'd like to discuss a feature or bug fix before starting work, please [create an issue](https://github.com/aserafin/grape_logging/issues) first. This helps ensure your contribution aligns with the project's direction and avoids duplicate efforts.
|
||||||
|
|
||||||
|
## Rebase
|
||||||
|
|
||||||
|
If you've been working on a change for a while, rebase with upstream/master.
|
||||||
|
|
||||||
|
```
|
||||||
|
git fetch upstream
|
||||||
|
git rebase upstream/master
|
||||||
|
git push origin my-feature-branch -f
|
||||||
|
```
|
||||||
|
|
||||||
|
## Be Patient
|
||||||
|
|
||||||
|
It's likely that your change will not be merged and that the nitpicky maintainers will ask you to do more, or fix seemingly benign problems. Hang in there!
|
||||||
|
|
||||||
|
## Thank You
|
||||||
|
|
||||||
|
Please do know that we really appreciate and value your time and work. We love you, really.
|
||||||
7
Gemfile
7
Gemfile
|
|
@ -2,3 +2,10 @@ source 'https://rubygems.org'
|
||||||
|
|
||||||
# Specify your gem's dependencies in grape_logging.gemspec
|
# Specify your gem's dependencies in grape_logging.gemspec
|
||||||
gemspec
|
gemspec
|
||||||
|
|
||||||
|
gem 'rake', '~> 13.3'
|
||||||
|
gem 'rspec', '~> 3.5'
|
||||||
|
|
||||||
|
# This is pinned to an exact version otherwise we can't know which rules
|
||||||
|
# are in play at any given time in different environments.
|
||||||
|
gem 'rubocop', '1.77.0'
|
||||||
|
|
|
||||||
27
README.md
27
README.md
|
|
@ -1,7 +1,7 @@
|
||||||
# grape_logging
|
# grape_logging
|
||||||
|
|
||||||
[](https://codeclimate.com/github/aserafin/grape_logging)
|
[](https://badge.fury.io/rb/grape_logging)
|
||||||
[](https://travis-ci.org/aserafin/grape_logging)
|
[](https://github.com/aserafin/grape_logging/actions/workflows/ci.yml)
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
|
|
@ -19,12 +19,12 @@ Or install it yourself as:
|
||||||
|
|
||||||
## Basic Usage
|
## Basic Usage
|
||||||
|
|
||||||
In your api file (somewhere on the top)
|
In your API file (somewhere on the top), insert grape logging middleware before grape error middleware. This is important due to the behaviour of `lib/grape/middleware/error.rb`, which manipulates the status of the response when there is an error.
|
||||||
|
|
||||||
```ruby
|
```ruby
|
||||||
require 'grape_logging'
|
require 'grape_logging'
|
||||||
logger.formatter = GrapeLogging::Formatters::Default.new
|
logger.formatter = GrapeLogging::Formatters::Default.new
|
||||||
use GrapeLogging::Middleware::RequestLogger, { logger: logger }
|
insert_before Grape::Middleware::Error, GrapeLogging::Middleware::RequestLogger, { logger: logger }
|
||||||
```
|
```
|
||||||
|
|
||||||
**ProTip:** If your logger doesn't support setting formatter you can remove this line - it's optional
|
**ProTip:** If your logger doesn't support setting formatter you can remove this line - it's optional
|
||||||
|
|
@ -114,7 +114,7 @@ end
|
||||||
You can change the formatter like so
|
You can change the formatter like so
|
||||||
```ruby
|
```ruby
|
||||||
class MyAPI < Grape::API
|
class MyAPI < Grape::API
|
||||||
use GrapeLogging::Middleware::RequestLogger, logger: logger, formatter: MyFormatter.new
|
insert_before Grape::Middleware::Error, GrapeLogging::Middleware::RequestLogger, logger: logger, formatter: MyFormatter.new
|
||||||
end
|
end
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
@ -125,7 +125,8 @@ If you prefer some other format I strongly encourage you to do pull request with
|
||||||
You can include logging of other parts of the request / response cycle by including subclasses of `GrapeLogging::Loggers::Base`
|
You can include logging of other parts of the request / response cycle by including subclasses of `GrapeLogging::Loggers::Base`
|
||||||
```ruby
|
```ruby
|
||||||
class MyAPI < Grape::API
|
class MyAPI < Grape::API
|
||||||
use GrapeLogging::Middleware::RequestLogger,
|
insert_before Grape::Middleware::Error,
|
||||||
|
GrapeLogging::Middleware::RequestLogger,
|
||||||
logger: logger,
|
logger: logger,
|
||||||
include: [ GrapeLogging::Loggers::Response.new,
|
include: [ GrapeLogging::Loggers::Response.new,
|
||||||
GrapeLogging::Loggers::FilterParameters.new,
|
GrapeLogging::Loggers::FilterParameters.new,
|
||||||
|
|
@ -158,7 +159,8 @@ You can control the level used to log. The default is `info`.
|
||||||
|
|
||||||
```ruby
|
```ruby
|
||||||
class MyAPI < Grape::API
|
class MyAPI < Grape::API
|
||||||
use GrapeLogging::Middleware::RequestLogger,
|
insert_before Grape::Middleware::Error,
|
||||||
|
GrapeLogging::Middleware::RequestLogger,
|
||||||
logger: logger,
|
logger: logger,
|
||||||
log_level: 'debug'
|
log_level: 'debug'
|
||||||
end
|
end
|
||||||
|
|
@ -170,7 +172,8 @@ You can choose to not pass the logger to ```grape_logging``` but instead send lo
|
||||||
First, config ```grape_logging```, like that:
|
First, config ```grape_logging```, like that:
|
||||||
```ruby
|
```ruby
|
||||||
class MyAPI < Grape::API
|
class MyAPI < Grape::API
|
||||||
use GrapeLogging::Middleware::RequestLogger,
|
insert_before Grape::Middleware::Error,
|
||||||
|
GrapeLogging::Middleware::RequestLogger,
|
||||||
instrumentation_key: 'grape_key',
|
instrumentation_key: 'grape_key',
|
||||||
include: [ GrapeLogging::Loggers::Response.new,
|
include: [ GrapeLogging::Loggers::Response.new,
|
||||||
GrapeLogging::Loggers::FilterParameters.new ]
|
GrapeLogging::Loggers::FilterParameters.new ]
|
||||||
|
|
@ -206,10 +209,8 @@ After checking out the repo, run `bin/setup` to install dependencies. Then, run
|
||||||
|
|
||||||
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release` to create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release` to create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
||||||
|
|
||||||
|
For maintainers releasing a new version, please see [RELEASING.md](RELEASING.md).
|
||||||
|
|
||||||
## Contributing
|
## Contributing
|
||||||
|
|
||||||
1. Fork it ( https://github.com/aserafin/grape_logging/fork )
|
See [CONTRIBUTING.md](CONTRIBUTING.md).
|
||||||
2. Create your feature branch (`git checkout -b my-new-feature`)
|
|
||||||
3. Commit your changes (`git commit -am 'Add some feature'`)
|
|
||||||
4. Push to the branch (`git push origin my-new-feature`)
|
|
||||||
5. Create a new Pull Request
|
|
||||||
|
|
|
||||||
113
RELEASING.md
Normal file
113
RELEASING.md
Normal file
|
|
@ -0,0 +1,113 @@
|
||||||
|
# Releasing grape_logging
|
||||||
|
|
||||||
|
There're no particular rules about when to release grape_logging. Release bug fixes frequently, features not so frequently and breaking API changes rarely.
|
||||||
|
|
||||||
|
### Pre-flight Checks
|
||||||
|
|
||||||
|
Run tests, check that all tests succeed locally.
|
||||||
|
|
||||||
|
```
|
||||||
|
bundle install
|
||||||
|
rake
|
||||||
|
```
|
||||||
|
|
||||||
|
Check that the last build succeeded in [GitHub Actions](https://github.com/aserafin/grape_logging/actions) for all supported platforms.
|
||||||
|
|
||||||
|
### Update Changelog
|
||||||
|
|
||||||
|
Change "Unreleased" in [CHANGELOG.md](https://github.com/aserafin/grape_logging/blob/master/CHANGELOG.md) to the new version and date:
|
||||||
|
|
||||||
|
```
|
||||||
|
## [1.8.5] - 2024-06-28
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
- Description of changes
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
- Description of fixes
|
||||||
|
|
||||||
|
### Added
|
||||||
|
- Description of additions
|
||||||
|
|
||||||
|
[1.8.5]: https://github.com/aserafin/grape_logging/compare/v1.8.4...v1.8.5
|
||||||
|
```
|
||||||
|
|
||||||
|
Remove the line with "Your contribution here.", since there will be no more contributions to this release.
|
||||||
|
|
||||||
|
Only include the sections (Changed, Fixed, Added, etc.) that have actual changes.
|
||||||
|
|
||||||
|
Commit your changes.
|
||||||
|
|
||||||
|
```shell
|
||||||
|
git add CHANGELOG.md lib/grape_logging/version.rb
|
||||||
|
git commit -m "Preparing for release, 1.8.5."
|
||||||
|
git push
|
||||||
|
```
|
||||||
|
|
||||||
|
### Release on RubyGems and GitHub
|
||||||
|
|
||||||
|
#### Option 1: Automated (Recommended)
|
||||||
|
|
||||||
|
Use the combined task that releases the gem and creates a GitHub release:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
rake github_release
|
||||||
|
```
|
||||||
|
|
||||||
|
This will:
|
||||||
|
1. Build and push the gem to RubyGems
|
||||||
|
2. Create and push the git tag
|
||||||
|
3. Create a GitHub release with auto-generated changelog
|
||||||
|
|
||||||
|
#### Option 2: Manual
|
||||||
|
|
||||||
|
First, release the gem:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
rake release
|
||||||
|
```
|
||||||
|
|
||||||
|
Output will look something like:
|
||||||
|
```
|
||||||
|
grape_logging 1.8.5 built to pkg/grape_logging-1.8.5.gem.
|
||||||
|
Tagged v1.8.5.
|
||||||
|
Pushed git commits and tags.
|
||||||
|
Pushed grape_logging 1.8.5 to rubygems.org.
|
||||||
|
```
|
||||||
|
|
||||||
|
Then create the GitHub release on the web or using `gh`:
|
||||||
|
|
||||||
|
```
|
||||||
|
gh release create v1.8.5 --generate-notes --verify-tag
|
||||||
|
```
|
||||||
|
|
||||||
|
This uses GitHub's automatic changelog generation feature to create release notes from merged pull requests and commits since the last release.
|
||||||
|
|
||||||
|
### Prepare for the Next Version
|
||||||
|
|
||||||
|
Modify `lib/grape_logging/version.rb`, increment the version number (eg. change `1.8.5` to `1.8.6`).
|
||||||
|
|
||||||
|
```ruby
|
||||||
|
module GrapeLogging
|
||||||
|
VERSION = '1.8.6'.freeze
|
||||||
|
end
|
||||||
|
```
|
||||||
|
|
||||||
|
Add the next release to [CHANGELOG.md](https://github.com/aserafin/grape_logging/blob/master/CHANGELOG.md).
|
||||||
|
|
||||||
|
```
|
||||||
|
## [1.8.6] - Unreleased
|
||||||
|
|
||||||
|
### Changed or Fixed or Added
|
||||||
|
- Your contribution here.
|
||||||
|
|
||||||
|
[1.8.6]: https://github.com/aserafin/grape_logging/compare/v1.8.5...master
|
||||||
|
```
|
||||||
|
|
||||||
|
Commit your changes.
|
||||||
|
|
||||||
|
```
|
||||||
|
git add CHANGELOG.md lib/grape_logging/version.rb
|
||||||
|
git commit -m "Bump version to 1.8.6."
|
||||||
|
git push
|
||||||
|
```
|
||||||
41
Rakefile
41
Rakefile
|
|
@ -1,2 +1,43 @@
|
||||||
require 'bundler/gem_tasks'
|
require 'bundler/gem_tasks'
|
||||||
|
require 'rspec/core/rake_task'
|
||||||
|
require 'rubocop/rake_task'
|
||||||
|
|
||||||
|
RSpec::Core::RakeTask.new(:spec) do |spec|
|
||||||
|
spec.rspec_opts = ['-fd -c']
|
||||||
|
spec.pattern = FileList['spec/**/*_spec.rb']
|
||||||
|
end
|
||||||
|
|
||||||
|
RuboCop::RakeTask.new(:rubocop) do |t|
|
||||||
|
t.patterns = ['lib/**/*.rb', 'spec/**/*.rb', 'Rakefile', 'Gemfile', 'grape_logging.gemspec']
|
||||||
|
end
|
||||||
|
|
||||||
|
task default: %i[spec rubocop]
|
||||||
|
|
||||||
|
desc 'Release gem and create GitHub release'
|
||||||
|
task github_release: :release do
|
||||||
|
require 'grape_logging/version'
|
||||||
|
|
||||||
|
version = "v#{GrapeLogging::VERSION}"
|
||||||
|
|
||||||
|
# Check if gh CLI is available
|
||||||
|
unless system('which gh > /dev/null 2>&1')
|
||||||
|
puts "\n⚠️ GitHub CLI (gh) not found"
|
||||||
|
puts 'To create a GitHub release with auto-generated changelog, install gh:'
|
||||||
|
puts ' brew install gh # macOS with Homebrew'
|
||||||
|
puts ' # or visit: https://github.com/cli/cli#installation'
|
||||||
|
puts "\nYou can manually create the release with:"
|
||||||
|
puts " gh release create v#{GrapeLogging::VERSION} --generate-notes"
|
||||||
|
next
|
||||||
|
end
|
||||||
|
|
||||||
|
# Create GitHub release
|
||||||
|
puts "\nCreating GitHub release #{version}..."
|
||||||
|
|
||||||
|
if system('gh', 'release', 'create', version, '--generate-notes', '--verify-tag')
|
||||||
|
puts "✅ GitHub release #{version} created successfully"
|
||||||
|
else
|
||||||
|
puts '❌ Failed to create GitHub release'
|
||||||
|
puts 'You can manually create it with:'
|
||||||
|
puts " gh release create '#{version}' --generate-notes --verify-tag"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
|
||||||
0
bin/console
Normal file → Executable file
0
bin/console
Normal file → Executable file
|
|
@ -1,29 +1,26 @@
|
||||||
# coding: utf-8
|
lib = File.expand_path('lib', __dir__)
|
||||||
lib = File.expand_path('../lib', __FILE__)
|
|
||||||
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
||||||
require 'grape_logging/version'
|
require 'grape_logging/version'
|
||||||
|
|
||||||
Gem::Specification.new do |spec|
|
Gem::Specification.new do |spec|
|
||||||
spec.name = 'grape_logging'
|
spec.name = 'grape_logging'
|
||||||
spec.version = GrapeLogging::VERSION
|
spec.version = GrapeLogging::VERSION
|
||||||
spec.authors = ['aserafin']
|
spec.authors = ['aserafin', 'Sami Samhuri']
|
||||||
spec.email = ['adrian@softmad.pl']
|
spec.email = ['adrian@softmad.pl', 'sami@samhuri.net']
|
||||||
|
|
||||||
spec.summary = %q{Out of the box request logging for Grape!}
|
spec.summary = 'Out of the box request logging for Grape!'
|
||||||
spec.description = %q{This gem provides simple request logging for Grape with just few lines of code you have to put in your project! In return you will get response codes, paths, parameters and more!}
|
spec.description = 'This gem provides simple request logging for Grape with just few lines ' \
|
||||||
|
'of code you have to put in your project! In return you will get response ' \
|
||||||
|
'codes, paths, parameters and more!'
|
||||||
spec.homepage = 'http://github.com/aserafin/grape_logging'
|
spec.homepage = 'http://github.com/aserafin/grape_logging'
|
||||||
spec.license = 'MIT'
|
spec.license = 'MIT'
|
||||||
|
|
||||||
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
||||||
spec.bindir = "exe"
|
spec.bindir = 'exe'
|
||||||
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
||||||
spec.require_paths = ['lib']
|
spec.require_paths = ['lib']
|
||||||
|
|
||||||
spec.add_dependency 'grape'
|
spec.add_dependency 'grape', '>= 2.4.0'
|
||||||
spec.add_dependency 'rack'
|
spec.add_dependency 'rack'
|
||||||
|
spec.add_dependency 'zeitwerk'
|
||||||
spec.add_development_dependency 'bundler', '~> 1.8'
|
|
||||||
spec.add_development_dependency 'rake', '~> 10.0'
|
|
||||||
spec.add_development_dependency 'rspec', '~> 3.5'
|
|
||||||
spec.add_development_dependency 'pry-byebug', '~> 3.4.2'
|
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -1,17 +1,12 @@
|
||||||
require 'grape_logging/multi_io'
|
require 'grape'
|
||||||
require 'grape_logging/version'
|
require 'rack/utils'
|
||||||
require 'grape_logging/formatters/default'
|
require 'zeitwerk'
|
||||||
require 'grape_logging/formatters/json'
|
|
||||||
require 'grape_logging/formatters/lograge'
|
# load zeitwerk
|
||||||
require 'grape_logging/formatters/logstash'
|
Zeitwerk::Loader.for_gem.tap do |loader|
|
||||||
require 'grape_logging/formatters/rails'
|
loader.inflector.inflect 'multi_io' => 'MultiIO'
|
||||||
require 'grape_logging/loggers/base'
|
loader.setup
|
||||||
require 'grape_logging/loggers/response'
|
end
|
||||||
require 'grape_logging/loggers/filter_parameters'
|
|
||||||
require 'grape_logging/loggers/client_env'
|
module GrapeLogging
|
||||||
require 'grape_logging/loggers/request_headers'
|
end
|
||||||
require 'grape_logging/reporters/active_support_reporter'
|
|
||||||
require 'grape_logging/reporters/logger_reporter'
|
|
||||||
require 'grape_logging/timings'
|
|
||||||
require 'grape_logging/middleware/request_logger'
|
|
||||||
require 'grape_logging/util/parameter_filter'
|
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,7 @@ module GrapeLogging
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def format_hash(hash)
|
def format_hash(hash)
|
||||||
hash.keys.sort.map { |key| "#{key}=#{hash[key]}" }.join(' ')
|
hash.keys.sort.map { |key| "#{key}=#{hash[key]}" }.join(' ')
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -3,9 +3,9 @@ module GrapeLogging
|
||||||
class Logstash
|
class Logstash
|
||||||
def call(severity, datetime, _, data)
|
def call(severity, datetime, _, data)
|
||||||
{
|
{
|
||||||
:'@timestamp' => datetime.iso8601,
|
'@timestamp': datetime.iso8601,
|
||||||
:'@version' => '1',
|
'@version': '1',
|
||||||
:severity => severity
|
severity: severity
|
||||||
}.merge!(format(data)).to_json + "\n"
|
}.merge!(format(data)).to_json + "\n"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,6 @@
|
||||||
require 'rack/utils'
|
|
||||||
|
|
||||||
module GrapeLogging
|
module GrapeLogging
|
||||||
module Formatters
|
module Formatters
|
||||||
class Rails
|
class Rails
|
||||||
|
|
||||||
def call(severity, datetime, _, data)
|
def call(severity, datetime, _, data)
|
||||||
if data.is_a?(String)
|
if data.is_a?(String)
|
||||||
"#{severity[0..0]} [#{datetime}] #{severity} -- : #{data}\n"
|
"#{severity[0..0]} [#{datetime}] #{severity} -- : #{data}\n"
|
||||||
|
|
@ -24,7 +21,7 @@ module GrapeLogging
|
||||||
[
|
[
|
||||||
"#{exception.message} (#{exception.class})",
|
"#{exception.message} (#{exception.class})",
|
||||||
backtrace_array.join("\n")
|
backtrace_array.join("\n")
|
||||||
].reject{|line| line == ""}.join("\n")
|
].reject { |line| line == '' }.join("\n")
|
||||||
end
|
end
|
||||||
|
|
||||||
def format_hash(hash)
|
def format_hash(hash)
|
||||||
|
|
@ -32,7 +29,7 @@ module GrapeLogging
|
||||||
# Completed 200 OK in 958ms (Views: 951.1ms | ActiveRecord: 3.8ms)
|
# Completed 200 OK in 958ms (Views: 951.1ms | ActiveRecord: 3.8ms)
|
||||||
# See: actionpack/lib/action_controller/log_subscriber.rb
|
# See: actionpack/lib/action_controller/log_subscriber.rb
|
||||||
|
|
||||||
message = ""
|
message = ''
|
||||||
additions = []
|
additions = []
|
||||||
status = hash.delete(:status)
|
status = hash.delete(:status)
|
||||||
params = hash.delete(:params)
|
params = hash.delete(:params)
|
||||||
|
|
@ -47,13 +44,12 @@ module GrapeLogging
|
||||||
message << " Parameters: #{params.inspect}\n" if params
|
message << " Parameters: #{params.inspect}\n" if params
|
||||||
|
|
||||||
message << "Completed #{status} #{::Rack::Utils::HTTP_STATUS_CODES[status]} in #{total_time}ms"
|
message << "Completed #{status} #{::Rack::Utils::HTTP_STATUS_CODES[status]} in #{total_time}ms"
|
||||||
message << " (#{additions.join(" | ".freeze)})" if additions.size > 0
|
message << " (#{additions.join(' | '.freeze)})" unless additions.empty?
|
||||||
message << "\n"
|
message << "\n"
|
||||||
message << "\n" if defined?(::Rails.env) && ::Rails.env.development?
|
message << "\n" if defined?(::Rails.env) && ::Rails.env.development?
|
||||||
|
|
||||||
message
|
message
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
module GrapeLogging
|
module GrapeLogging
|
||||||
module Loggers
|
module Loggers
|
||||||
class Base
|
class Base
|
||||||
def parameters(request, response)
|
def parameters(_request, _response)
|
||||||
{}
|
{}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ module GrapeLogging
|
||||||
module Loggers
|
module Loggers
|
||||||
class ClientEnv < GrapeLogging::Loggers::Base
|
class ClientEnv < GrapeLogging::Loggers::Base
|
||||||
def parameters(request, _)
|
def parameters(request, _)
|
||||||
{ ip: request.env["HTTP_X_FORWARDED_FOR"] || request.env["REMOTE_ADDR"], ua: request.env["HTTP_USER_AGENT"] }
|
{ ip: request.env['HTTP_X_FORWARDED_FOR'] || request.env['REMOTE_ADDR'], ua: request.env['HTTP_USER_AGENT'] }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ module GrapeLogging
|
||||||
class FilterParameters < GrapeLogging::Loggers::Base
|
class FilterParameters < GrapeLogging::Loggers::Base
|
||||||
AD_PARAMS = 'action_dispatch.request.parameters'.freeze
|
AD_PARAMS = 'action_dispatch.request.parameters'.freeze
|
||||||
|
|
||||||
def initialize(filter_parameters = nil, replacement = nil, exceptions = %w(controller action format))
|
def initialize(filter_parameters = nil, replacement = nil, exceptions = %w[controller action format])
|
||||||
@filter_parameters = filter_parameters || (defined?(::Rails.application) ? ::Rails.application.config.filter_parameters : [])
|
@filter_parameters = filter_parameters || (defined?(::Rails.application) ? ::Rails.application.config.filter_parameters : [])
|
||||||
@replacement = replacement || '[FILTERED]'
|
@replacement = replacement || '[FILTERED]'
|
||||||
@exceptions = exceptions
|
@exceptions = exceptions
|
||||||
|
|
@ -16,7 +16,7 @@ module GrapeLogging
|
||||||
private
|
private
|
||||||
|
|
||||||
def parameter_filter
|
def parameter_filter
|
||||||
@parameter_filter ||= ParameterFilter.new(@replacement, @filter_parameters)
|
@parameter_filter ||= GrapeLogging::Util::ParameterFilter.new(@replacement, @filter_parameters)
|
||||||
end
|
end
|
||||||
|
|
||||||
def safe_parameters(request)
|
def safe_parameters(request)
|
||||||
|
|
@ -29,7 +29,25 @@ module GrapeLogging
|
||||||
end
|
end
|
||||||
|
|
||||||
def clean_parameters(parameters)
|
def clean_parameters(parameters)
|
||||||
parameter_filter.filter(parameters).reject{ |key, _value| @exceptions.include?(key) }
|
original_encoding_map = build_encoding_map(parameters)
|
||||||
|
params = transform_key_encoding(parameters, Hash.new { |h, _| [Encoding::ASCII_8BIT, h] })
|
||||||
|
cleaned_params = parameter_filter.filter(params).except(*@exceptions)
|
||||||
|
transform_key_encoding(cleaned_params, original_encoding_map)
|
||||||
|
end
|
||||||
|
|
||||||
|
def build_encoding_map(parameters)
|
||||||
|
parameters.each_with_object({}) do |(k, v), h|
|
||||||
|
key_str = k.to_s
|
||||||
|
h[key_str.dup.force_encoding(Encoding::ASCII_8BIT)] = [key_str.encoding, v.is_a?(Hash) ? build_encoding_map(v) : nil]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def transform_key_encoding(parameters, encoding_map)
|
||||||
|
parameters.each_with_object({}) do |(k, v), h|
|
||||||
|
key_str = k.to_s
|
||||||
|
encoding, children_encoding_map = encoding_map[key_str]
|
||||||
|
h[key_str.dup.force_encoding(encoding)] = v.is_a?(Hash) ? transform_key_encoding(v, children_encoding_map) : v
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
module GrapeLogging
|
module GrapeLogging
|
||||||
module Loggers
|
module Loggers
|
||||||
class RequestHeaders < GrapeLogging::Loggers::Base
|
class RequestHeaders < GrapeLogging::Loggers::Base
|
||||||
|
|
||||||
HTTP_PREFIX = 'HTTP_'.freeze
|
HTTP_PREFIX = 'HTTP_'.freeze
|
||||||
|
|
||||||
def parameters(request, _)
|
def parameters(request, _)
|
||||||
|
|
@ -16,7 +15,6 @@ module GrapeLogging
|
||||||
|
|
||||||
{ headers: headers }
|
{ headers: headers }
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -9,14 +9,13 @@ module GrapeLogging
|
||||||
|
|
||||||
# In some cases, response.body is not parseable by JSON.
|
# In some cases, response.body is not parseable by JSON.
|
||||||
# For example, if you POST on a PUT endpoint, response.body is egal to """".
|
# For example, if you POST on a PUT endpoint, response.body is egal to """".
|
||||||
# It's strange but it's the Grape behavior...
|
# It's strange, but it's the Grape behavior...
|
||||||
def serialized_response_body(response)
|
def serialized_response_body(response)
|
||||||
|
|
||||||
if response.respond_to?(:body)
|
if response.respond_to?(:body)
|
||||||
# Rack responses
|
# Rack responses
|
||||||
begin
|
begin
|
||||||
response.body.map{ |body| JSON.parse(body.to_s) }
|
response.body.map { |body| JSON.parse(body.to_s) }
|
||||||
rescue # No reason to have "=> e" here when we don't use it..
|
rescue StandardError # No reason to have "=> e" here when we don't use it..
|
||||||
response.body
|
response.body
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
|
|
|
||||||
|
|
@ -1,27 +1,27 @@
|
||||||
require 'grape/middleware/base'
|
|
||||||
|
|
||||||
module GrapeLogging
|
module GrapeLogging
|
||||||
module Middleware
|
module Middleware
|
||||||
class RequestLogger < Grape::Middleware::Base
|
class RequestLogger < Grape::Middleware::Base
|
||||||
|
if defined?(ActiveRecord)
|
||||||
ActiveSupport::Notifications.subscribe('sql.active_record') do |*args|
|
ActiveSupport::Notifications.subscribe('sql.active_record') do |*args|
|
||||||
event = ActiveSupport::Notifications::Event.new(*args)
|
event = ActiveSupport::Notifications::Event.new(*args)
|
||||||
GrapeLogging::Timings.append_db_runtime(event)
|
GrapeLogging::Timings.append_db_runtime(event)
|
||||||
end if defined?(ActiveRecord)
|
end
|
||||||
|
end
|
||||||
|
|
||||||
# Persist response status & response (body)
|
# Persist response status & response (body)
|
||||||
# to use int in parameters
|
# to use int in parameters
|
||||||
attr_accessor :response_status, :response_body
|
attr_accessor :response_status, :response_body
|
||||||
|
|
||||||
def initialize(app, options = {})
|
def initialize(app, **options)
|
||||||
super
|
super
|
||||||
|
|
||||||
@included_loggers = @options[:include] || []
|
@included_loggers = @options[:include] || []
|
||||||
@reporter = if options[:instrumentation_key]
|
@reporter =
|
||||||
Reporters::ActiveSupportReporter.new(@options[:instrumentation_key])
|
if options[:instrumentation_key]
|
||||||
else
|
Reporters::ActiveSupportReporter.new(@options[:instrumentation_key])
|
||||||
Reporters::LoggerReporter.new(@options[:logger], @options[:formatter], @options[:log_level])
|
else
|
||||||
end
|
Reporters::LoggerReporter.new(@options[:logger], @options[:formatter], @options[:log_level])
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def before
|
def before
|
||||||
|
|
@ -37,7 +37,7 @@ module GrapeLogging
|
||||||
@response_status = status
|
@response_status = status
|
||||||
@response_body = response
|
@response_body = response
|
||||||
|
|
||||||
# Perform repotters
|
# Perform reporters
|
||||||
@reporter.perform(collect_parameters)
|
@reporter.perform(collect_parameters)
|
||||||
|
|
||||||
# Invoke loggers
|
# Invoke loggers
|
||||||
|
|
@ -56,20 +56,18 @@ module GrapeLogging
|
||||||
|
|
||||||
# Catch error
|
# Catch error
|
||||||
error = catch(:error) do
|
error = catch(:error) do
|
||||||
begin
|
@app_response = @app.call(@env)
|
||||||
@app_response = @app.call(@env)
|
|
||||||
rescue => e
|
|
||||||
# Log as 500 + message
|
|
||||||
after(e.respond_to?(:status) ? e.status : 500, e.message)
|
|
||||||
|
|
||||||
# Re-raise exception
|
|
||||||
raise e
|
|
||||||
end
|
|
||||||
nil
|
nil
|
||||||
|
rescue StandardError => e
|
||||||
|
# Log as 500 + message
|
||||||
|
after(e.respond_to?(:status) ? e.status : 500, e.message)
|
||||||
|
|
||||||
|
# Re-raise exception
|
||||||
|
raise e
|
||||||
end
|
end
|
||||||
|
|
||||||
# Get status & response from app_response
|
# Get status & response from app_response
|
||||||
# when no error occures.
|
# when no error occurs.
|
||||||
if error
|
if error
|
||||||
# Call with error & response
|
# Call with error & response
|
||||||
after(error[:status], error[:message])
|
after(error[:status], error[:message])
|
||||||
|
|
@ -100,7 +98,8 @@ module GrapeLogging
|
||||||
method: request.request_method,
|
method: request.request_method,
|
||||||
path: request.path,
|
path: request.path,
|
||||||
params: request.params,
|
params: request.params,
|
||||||
host: request.host
|
host: request.host,
|
||||||
|
request_id: env['action_dispatch.request_id']
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -115,7 +114,7 @@ module GrapeLogging
|
||||||
end
|
end
|
||||||
|
|
||||||
def view_runtime
|
def view_runtime
|
||||||
total_runtime - db_runtime
|
(total_runtime - db_runtime).round(2)
|
||||||
end
|
end
|
||||||
|
|
||||||
def db_runtime
|
def db_runtime
|
||||||
|
|
|
||||||
|
|
@ -5,11 +5,11 @@ module GrapeLogging
|
||||||
end
|
end
|
||||||
|
|
||||||
def write(*args)
|
def write(*args)
|
||||||
@targets.each {|t| t.write(*args)}
|
@targets.each { |t| t.write(*args) }
|
||||||
end
|
end
|
||||||
|
|
||||||
def close
|
def close
|
||||||
@targets.each(&:close)
|
@targets.each(&:close)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,13 @@
|
||||||
module Reporters
|
module GrapeLogging
|
||||||
class ActiveSupportReporter
|
module Reporters
|
||||||
def initialize(instrumentation_key)
|
class ActiveSupportReporter
|
||||||
@instrumentation_key = instrumentation_key
|
def initialize(instrumentation_key)
|
||||||
end
|
@instrumentation_key = instrumentation_key
|
||||||
|
end
|
||||||
|
|
||||||
def perform(params)
|
def perform(params)
|
||||||
ActiveSupport::Notifications.instrument @instrumentation_key, params
|
ActiveSupport::Notifications.instrument @instrumentation_key, params
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -1,15 +1,15 @@
|
||||||
module Reporters
|
module GrapeLogging
|
||||||
class LoggerReporter
|
module Reporters
|
||||||
def initialize(logger, formatter, log_level)
|
class LoggerReporter
|
||||||
@logger = logger || Logger.new(STDOUT)
|
def initialize(logger, formatter, log_level)
|
||||||
@log_level = log_level || :info
|
@logger = logger.clone || Logger.new(STDOUT)
|
||||||
if @logger.respond_to?(:formatter=)
|
@log_level = log_level || :info
|
||||||
@logger.formatter = formatter || @logger.formatter || GrapeLogging::Formatters::Default.new
|
@logger.formatter = formatter || @logger.formatter || GrapeLogging::Formatters::Default.new if @logger.respond_to?(:formatter=)
|
||||||
end
|
end
|
||||||
end
|
|
||||||
|
|
||||||
def perform(params)
|
def perform(params)
|
||||||
@logger.send(@log_level, params)
|
@logger.send(@log_level, params)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -1,21 +1,19 @@
|
||||||
module GrapeLogging
|
module GrapeLogging
|
||||||
module Timings
|
module Timings
|
||||||
extend self
|
def self.db_runtime=(value)
|
||||||
|
|
||||||
def db_runtime=(value)
|
|
||||||
Thread.current[:grape_db_runtime] = value
|
Thread.current[:grape_db_runtime] = value
|
||||||
end
|
end
|
||||||
|
|
||||||
def db_runtime
|
def self.db_runtime
|
||||||
Thread.current[:grape_db_runtime] ||= 0
|
Thread.current[:grape_db_runtime] ||= 0
|
||||||
end
|
end
|
||||||
|
|
||||||
def reset_db_runtime
|
def self.reset_db_runtime
|
||||||
self.db_runtime = 0
|
self.db_runtime = 0
|
||||||
end
|
end
|
||||||
|
|
||||||
def append_db_runtime(event)
|
def self.append_db_runtime(event)
|
||||||
self.db_runtime += event.duration
|
self.db_runtime += event.duration
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -1,99 +1,105 @@
|
||||||
if defined?(::Rails.application)
|
module GrapeLogging
|
||||||
if Gem::Version.new(Rails.version) < Gem::Version.new('6.0.0')
|
module Util
|
||||||
class ParameterFilter < ActionDispatch::Http::ParameterFilter
|
if defined?(Rails.application)
|
||||||
def initialize(_replacement, filter_parameters)
|
if Gem::Version.new(Rails.version) < Gem::Version.new('6.0.0')
|
||||||
super(filter_parameters)
|
class ParameterFilter < ActionDispatch::Http::ParameterFilter
|
||||||
end
|
def initialize(_replacement, filter_parameters)
|
||||||
end
|
super(filter_parameters)
|
||||||
else
|
|
||||||
require "active_support/parameter_filter"
|
|
||||||
|
|
||||||
class ParameterFilter < ActiveSupport::ParameterFilter
|
|
||||||
def initialize(_replacement, filter_parameters)
|
|
||||||
super(filter_parameters)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
else
|
|
||||||
#
|
|
||||||
# lifted from https://github.com/rails/rails/blob/master/actionpack/lib/action_dispatch/http/parameter_filter.rb
|
|
||||||
# we could depend on Rails specifically, but that would us way to hefty!
|
|
||||||
#
|
|
||||||
class ParameterFilter
|
|
||||||
def initialize(replacement, filters = [])
|
|
||||||
@replacement = replacement
|
|
||||||
@filters = filters
|
|
||||||
end
|
|
||||||
|
|
||||||
def filter(params)
|
|
||||||
compiled_filter.call(params)
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
|
||||||
|
|
||||||
def compiled_filter
|
|
||||||
@compiled_filter ||= CompiledFilter.compile(@replacement, @filters)
|
|
||||||
end
|
|
||||||
|
|
||||||
class CompiledFilter # :nodoc:
|
|
||||||
def self.compile(replacement, filters)
|
|
||||||
return lambda { |params| params.dup } if filters.empty?
|
|
||||||
|
|
||||||
strings, regexps, blocks = [], [], []
|
|
||||||
|
|
||||||
filters.each do |item|
|
|
||||||
case item
|
|
||||||
when Proc
|
|
||||||
blocks << item
|
|
||||||
when Regexp
|
|
||||||
regexps << item
|
|
||||||
else
|
|
||||||
strings << Regexp.escape(item.to_s)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
else
|
||||||
|
require 'active_support/parameter_filter'
|
||||||
|
|
||||||
deep_regexps, regexps = regexps.partition { |r| r.to_s.include?("\\.".freeze) }
|
class ParameterFilter < ActiveSupport::ParameterFilter
|
||||||
deep_strings, strings = strings.partition { |s| s.include?("\\.".freeze) }
|
def initialize(_replacement, filter_parameters)
|
||||||
|
super(filter_parameters)
|
||||||
regexps << Regexp.new(strings.join('|'.freeze), true) unless strings.empty?
|
|
||||||
deep_regexps << Regexp.new(deep_strings.join('|'.freeze), true) unless deep_strings.empty?
|
|
||||||
|
|
||||||
new replacement, regexps, deep_regexps, blocks
|
|
||||||
end
|
|
||||||
|
|
||||||
attr_reader :regexps, :deep_regexps, :blocks
|
|
||||||
|
|
||||||
def initialize(replacement, regexps, deep_regexps, blocks)
|
|
||||||
@replacement = replacement
|
|
||||||
@regexps = regexps
|
|
||||||
@deep_regexps = deep_regexps.any? ? deep_regexps : nil
|
|
||||||
@blocks = blocks
|
|
||||||
end
|
|
||||||
|
|
||||||
def call(original_params, parents = [])
|
|
||||||
filtered_params = {}
|
|
||||||
|
|
||||||
original_params.each do |key, value|
|
|
||||||
parents.push(key) if deep_regexps
|
|
||||||
if regexps.any? { |r| key =~ r }
|
|
||||||
value = @replacement
|
|
||||||
elsif deep_regexps && (joined = parents.join('.')) && deep_regexps.any? { |r| joined =~ r }
|
|
||||||
value = @replacement
|
|
||||||
elsif value.is_a?(Hash)
|
|
||||||
value = call(value, parents)
|
|
||||||
elsif value.is_a?(Array)
|
|
||||||
value = value.map { |v| v.is_a?(Hash) ? call(v, parents) : v }
|
|
||||||
elsif blocks.any?
|
|
||||||
key = key.dup if key.duplicable?
|
|
||||||
value = value.dup if value.duplicable?
|
|
||||||
blocks.each { |b| b.call(key, value) }
|
|
||||||
end
|
end
|
||||||
parents.pop if deep_regexps
|
end
|
||||||
|
end
|
||||||
filtered_params[key] = value
|
else
|
||||||
|
#
|
||||||
|
# lifted from https://github.com/rails/rails/blob/master/actionpack/lib/action_dispatch/http/parameter_filter.rb
|
||||||
|
# we could depend on Rails specifically, but that would us way to hefty!
|
||||||
|
#
|
||||||
|
class ParameterFilter
|
||||||
|
def initialize(replacement, filters = [])
|
||||||
|
@replacement = replacement
|
||||||
|
@filters = filters
|
||||||
end
|
end
|
||||||
|
|
||||||
filtered_params
|
def filter(params)
|
||||||
|
compiled_filter.call(params)
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def compiled_filter
|
||||||
|
@compiled_filter ||= CompiledFilter.compile(@replacement, @filters)
|
||||||
|
end
|
||||||
|
|
||||||
|
class CompiledFilter # :nodoc:
|
||||||
|
def self.compile(replacement, filters)
|
||||||
|
return ->(params) { params.dup } if filters.empty?
|
||||||
|
|
||||||
|
strings = []
|
||||||
|
regexps = []
|
||||||
|
blocks = []
|
||||||
|
|
||||||
|
filters.each do |item|
|
||||||
|
case item
|
||||||
|
when Proc
|
||||||
|
blocks << item
|
||||||
|
when Regexp
|
||||||
|
regexps << item
|
||||||
|
else
|
||||||
|
strings << Regexp.escape(item.to_s)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
deep_regexps, regexps = regexps.partition { |r| r.to_s.include?('\\.'.freeze) }
|
||||||
|
deep_strings, strings = strings.partition { |s| s.include?('\\.'.freeze) }
|
||||||
|
|
||||||
|
regexps << Regexp.new(strings.join('|'.freeze), true) unless strings.empty?
|
||||||
|
deep_regexps << Regexp.new(deep_strings.join('|'.freeze), true) unless deep_strings.empty?
|
||||||
|
|
||||||
|
new replacement, regexps, deep_regexps, blocks
|
||||||
|
end
|
||||||
|
|
||||||
|
attr_reader :regexps, :deep_regexps, :blocks
|
||||||
|
|
||||||
|
def initialize(replacement, regexps, deep_regexps, blocks)
|
||||||
|
@replacement = replacement
|
||||||
|
@regexps = regexps
|
||||||
|
@deep_regexps = deep_regexps.any? ? deep_regexps : nil
|
||||||
|
@blocks = blocks
|
||||||
|
end
|
||||||
|
|
||||||
|
def call(original_params, parents = [])
|
||||||
|
filtered_params = {}
|
||||||
|
|
||||||
|
original_params.each do |key, value|
|
||||||
|
parents.push(key) if deep_regexps
|
||||||
|
if regexps.any? { |r| key =~ r }
|
||||||
|
value = @replacement
|
||||||
|
elsif deep_regexps && (joined = parents.join('.')) && deep_regexps.any? { |r| joined =~ r }
|
||||||
|
value = @replacement
|
||||||
|
elsif value.is_a?(Hash)
|
||||||
|
value = call(value, parents)
|
||||||
|
elsif value.is_a?(Array)
|
||||||
|
value = value.map { |v| v.is_a?(Hash) ? call(v, parents) : v }
|
||||||
|
elsif blocks.any?
|
||||||
|
key = key.dup if key.duplicable?
|
||||||
|
value = value.dup if value.duplicable?
|
||||||
|
blocks.each { |b| b.call(key, value) }
|
||||||
|
end
|
||||||
|
parents.pop if deep_regexps
|
||||||
|
|
||||||
|
filtered_params[key] = value
|
||||||
|
end
|
||||||
|
|
||||||
|
filtered_params
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,3 @@
|
||||||
module GrapeLogging
|
module GrapeLogging
|
||||||
VERSION = '1.8.4'
|
VERSION = '3.0.1'
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -2,11 +2,11 @@ require 'spec_helper'
|
||||||
|
|
||||||
describe GrapeLogging::Formatters::Rails do
|
describe GrapeLogging::Formatters::Rails do
|
||||||
let(:formatter) { described_class.new }
|
let(:formatter) { described_class.new }
|
||||||
let(:severity) { "INFO" }
|
let(:severity) { 'INFO' }
|
||||||
let(:datetime) { Time.new('2018', '03', '02', '10', '35', '04', '+13:00') }
|
let(:datetime) { Time.new('2018', '03', '02', '10', '35', '04', '+13:00') }
|
||||||
|
|
||||||
let(:exception_data) { ArgumentError.new('Message') }
|
let(:exception_data) { ArgumentError.new('Message') }
|
||||||
let(:hash_data) {
|
let(:hash_data) do
|
||||||
{
|
{
|
||||||
status: 200,
|
status: 200,
|
||||||
time: {
|
time: {
|
||||||
|
|
@ -14,11 +14,11 @@ describe GrapeLogging::Formatters::Rails do
|
||||||
db: 40.63,
|
db: 40.63,
|
||||||
view: 231.76999999999998
|
view: 231.76999999999998
|
||||||
},
|
},
|
||||||
method: "GET",
|
method: 'GET',
|
||||||
path: "/api/endpoint",
|
path: '/api/endpoint',
|
||||||
host: "localhost"
|
host: 'localhost'
|
||||||
}
|
}
|
||||||
}
|
end
|
||||||
|
|
||||||
describe '#call' do
|
describe '#call' do
|
||||||
context 'string data' do
|
context 'string data' do
|
||||||
|
|
@ -36,8 +36,8 @@ describe GrapeLogging::Formatters::Rails do
|
||||||
message = formatter.call(severity, datetime, nil, exception_data)
|
message = formatter.call(severity, datetime, nil, exception_data)
|
||||||
lines = message.split("\n")
|
lines = message.split("\n")
|
||||||
|
|
||||||
expect(lines[0]).to eq "I [2018-03-02 10:35:04 +1300] INFO -- : Message (ArgumentError)"
|
expect(lines[0]).to eq 'I [2018-03-02 10:35:04 +1300] INFO -- : Message (ArgumentError)'
|
||||||
expect(lines[1]).to include 'grape_logging'
|
expect(lines[1]).to include '.rb'
|
||||||
expect(lines.size).to be > 1
|
expect(lines.size).to be > 1
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
@ -52,9 +52,9 @@ describe GrapeLogging::Formatters::Rails do
|
||||||
it 'includes params if included (from GrapeLogging::Loggers::FilterParameters)' do
|
it 'includes params if included (from GrapeLogging::Loggers::FilterParameters)' do
|
||||||
hash_data.merge!(
|
hash_data.merge!(
|
||||||
params: {
|
params: {
|
||||||
"some_param" => {
|
'some_param' => {
|
||||||
value_1: "123",
|
value_1: '123',
|
||||||
value_2: "456"
|
value_2: '456'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
@ -62,12 +62,18 @@ describe GrapeLogging::Formatters::Rails do
|
||||||
message = formatter.call(severity, datetime, nil, hash_data)
|
message = formatter.call(severity, datetime, nil, hash_data)
|
||||||
lines = message.split("\n")
|
lines = message.split("\n")
|
||||||
|
|
||||||
expect(lines.first).to eq ' Parameters: {"some_param"=>{:value_1=>"123", :value_2=>"456"}}'
|
expected_output =
|
||||||
expect(lines.last).to eq "Completed 200 OK in 272.4ms (Views: 231.77ms | DB: 40.63ms)"
|
if RUBY_VERSION >= '3.4'
|
||||||
|
' Parameters: {"some_param" => {value_1: "123", value_2: "456"}}'
|
||||||
|
else
|
||||||
|
' Parameters: {"some_param"=>{:value_1=>"123", :value_2=>"456"}}'
|
||||||
|
end
|
||||||
|
expect(lines.first).to eq expected_output
|
||||||
|
expect(lines.last).to eq 'Completed 200 OK in 272.4ms (Views: 231.77ms | DB: 40.63ms)'
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context "unhandled data" do
|
context 'unhandled data' do
|
||||||
it 'returns the #inspect string representation' do
|
it 'returns the #inspect string representation' do
|
||||||
message = formatter.call(severity, datetime, nil, [1, 2, 3])
|
message = formatter.call(severity, datetime, nil, [1, 2, 3])
|
||||||
|
|
||||||
|
|
@ -75,5 +81,4 @@ describe GrapeLogging::Formatters::Rails do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -1,17 +1,16 @@
|
||||||
require 'spec_helper'
|
require 'spec_helper'
|
||||||
require 'ostruct'
|
|
||||||
|
|
||||||
describe GrapeLogging::Loggers::ClientEnv do
|
describe GrapeLogging::Loggers::ClientEnv do
|
||||||
let(:ip) { '10.0.0.1' }
|
let(:ip) { '10.0.0.1' }
|
||||||
let(:user_agent) { 'user agent' }
|
let(:user_agent) { 'user agent' }
|
||||||
let(:forwarded_for) { "forwarded for" }
|
let(:forwarded_for) { 'forwarded for' }
|
||||||
let(:remote_addr) { "remote address" }
|
let(:remote_addr) { 'remote address' }
|
||||||
|
|
||||||
context 'forwarded for' do
|
context 'forwarded for' do
|
||||||
let(:mock_request) do
|
let(:mock_request) do
|
||||||
OpenStruct.new(env: {
|
instance_double(Rack::Request, env: {
|
||||||
"HTTP_X_FORWARDED_FOR" => forwarded_for
|
'HTTP_X_FORWARDED_FOR' => forwarded_for
|
||||||
})
|
})
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'sets the ip key' do
|
it 'sets the ip key' do
|
||||||
|
|
@ -26,9 +25,9 @@ describe GrapeLogging::Loggers::ClientEnv do
|
||||||
|
|
||||||
context 'remote address' do
|
context 'remote address' do
|
||||||
let(:mock_request) do
|
let(:mock_request) do
|
||||||
OpenStruct.new(env: {
|
instance_double(Rack::Request, env: {
|
||||||
"REMOTE_ADDR" => remote_addr
|
'REMOTE_ADDR' => remote_addr
|
||||||
})
|
})
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'sets the ip key' do
|
it 'sets the ip key' do
|
||||||
|
|
@ -38,9 +37,9 @@ describe GrapeLogging::Loggers::ClientEnv do
|
||||||
|
|
||||||
context 'user agent' do
|
context 'user agent' do
|
||||||
let(:mock_request) do
|
let(:mock_request) do
|
||||||
OpenStruct.new(env: {
|
instance_double(Rack::Request, env: {
|
||||||
"HTTP_USER_AGENT" => user_agent
|
'HTTP_USER_AGENT' => user_agent
|
||||||
})
|
})
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'sets the ua key' do
|
it 'sets the ua key' do
|
||||||
|
|
|
||||||
|
|
@ -1,29 +1,27 @@
|
||||||
require 'spec_helper'
|
require 'spec_helper'
|
||||||
require 'ostruct'
|
|
||||||
|
|
||||||
|
|
||||||
describe GrapeLogging::Loggers::FilterParameters do
|
describe GrapeLogging::Loggers::FilterParameters do
|
||||||
let(:filtered_parameters) { %w[one four] }
|
let(:filtered_parameters) { %w[one four] }
|
||||||
|
|
||||||
let(:mock_request) do
|
let(:mock_request) do
|
||||||
OpenStruct.new(params: {
|
instance_double(Rack::Request, params: {
|
||||||
this_one: 'this one',
|
'this_one' => 'this one',
|
||||||
that_one: 'one',
|
'that_one' => 'one',
|
||||||
two: 'two',
|
'two' => 'two',
|
||||||
three: 'three',
|
'three' => 'three',
|
||||||
four: 'four'
|
'four' => 'four',
|
||||||
})
|
"\xff" => 'invalid utf8'
|
||||||
|
})
|
||||||
end
|
end
|
||||||
|
|
||||||
let(:mock_request_with_deep_nesting) do
|
let(:mock_request_with_deep_nesting) do
|
||||||
deep_clone = lambda { Marshal.load Marshal.dump mock_request.params }
|
deep_clone = -> { Marshal.load Marshal.dump mock_request.params }
|
||||||
OpenStruct.new(
|
instance_double(Rack::Request,
|
||||||
params: deep_clone.call.merge(
|
params: deep_clone.call.merge(
|
||||||
five: deep_clone.call.merge(
|
'five' => deep_clone.call.merge(
|
||||||
deep_clone.call.merge({six: {seven: 'seven', eight: 'eight', one: 'another one'}})
|
deep_clone.call.merge({ 'six' => { 'seven' => 'seven', 'eight' => 'eight', 'one' => 'another one' } })
|
||||||
)
|
)
|
||||||
)
|
))
|
||||||
)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
let(:subject) do
|
let(:subject) do
|
||||||
|
|
@ -35,34 +33,37 @@ describe GrapeLogging::Loggers::FilterParameters do
|
||||||
shared_examples 'filtering' do
|
shared_examples 'filtering' do
|
||||||
it 'filters out sensitive parameters' do
|
it 'filters out sensitive parameters' do
|
||||||
expect(subject.parameters(mock_request, nil)).to eq(params: {
|
expect(subject.parameters(mock_request, nil)).to eq(params: {
|
||||||
this_one: subject.instance_variable_get('@replacement'),
|
'this_one' => subject.instance_variable_get('@replacement'),
|
||||||
that_one: subject.instance_variable_get('@replacement'),
|
'that_one' => subject.instance_variable_get('@replacement'),
|
||||||
two: 'two',
|
'two' => 'two',
|
||||||
three: 'three',
|
'three' => 'three',
|
||||||
four: subject.instance_variable_get('@replacement'),
|
'four' => subject.instance_variable_get('@replacement'),
|
||||||
})
|
"\xff" => 'invalid utf8'
|
||||||
|
})
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'deeply filters out sensitive parameters' do
|
it 'deeply filters out sensitive parameters' do
|
||||||
expect(subject.parameters(mock_request_with_deep_nesting, nil)).to eq(params: {
|
expect(subject.parameters(mock_request_with_deep_nesting, nil)).to eq(params: {
|
||||||
this_one: subject.instance_variable_get('@replacement'),
|
'this_one' => subject.instance_variable_get('@replacement'),
|
||||||
that_one: subject.instance_variable_get('@replacement'),
|
'that_one' => subject.instance_variable_get('@replacement'),
|
||||||
two: 'two',
|
'two' => 'two',
|
||||||
three: 'three',
|
'three' => 'three',
|
||||||
four: subject.instance_variable_get('@replacement'),
|
'four' => subject.instance_variable_get('@replacement'),
|
||||||
five: {
|
"\xff" => 'invalid utf8',
|
||||||
this_one: subject.instance_variable_get('@replacement'),
|
'five' => {
|
||||||
that_one: subject.instance_variable_get('@replacement'),
|
'this_one' => subject.instance_variable_get('@replacement'),
|
||||||
two: 'two',
|
'that_one' => subject.instance_variable_get('@replacement'),
|
||||||
three: 'three',
|
'two' => 'two',
|
||||||
four: subject.instance_variable_get('@replacement'),
|
'three' => 'three',
|
||||||
six: {
|
'four' => subject.instance_variable_get('@replacement'),
|
||||||
seven: 'seven',
|
"\xff" => 'invalid utf8',
|
||||||
eight: 'eight',
|
'six' => {
|
||||||
one: subject.instance_variable_get('@replacement'),
|
'seven' => 'seven',
|
||||||
},
|
'eight' => 'eight',
|
||||||
},
|
'one' => subject.instance_variable_get('@replacement')
|
||||||
})
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -74,4 +75,14 @@ describe GrapeLogging::Loggers::FilterParameters do
|
||||||
let(:replacement) { 'CUSTOM_REPLACEMENT' }
|
let(:replacement) { 'CUSTOM_REPLACEMENT' }
|
||||||
it_behaves_like 'filtering'
|
it_behaves_like 'filtering'
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context 'with symbol keys, which occur during automated testing' do
|
||||||
|
let(:mock_request) { instance_double(Rack::Request, params: { sneaky_symbol: 'hey!' }) }
|
||||||
|
|
||||||
|
it 'converts keys to strings' do
|
||||||
|
expect(subject.parameters(mock_request, nil)).to eq(params: {
|
||||||
|
'sneaky_symbol' => 'hey!'
|
||||||
|
})
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -1,40 +1,45 @@
|
||||||
require 'spec_helper'
|
require 'spec_helper'
|
||||||
require 'ostruct'
|
|
||||||
|
|
||||||
describe GrapeLogging::Loggers::RequestHeaders do
|
describe GrapeLogging::Loggers::RequestHeaders do
|
||||||
let(:mock_request) do
|
let(:mock_request) do
|
||||||
OpenStruct.new(env: {HTTP_REFERER: 'http://example.com', HTTP_ACCEPT: 'text/plain'})
|
instance_double(Rack::Request, env: { HTTP_REFERER: 'http://example.com', HTTP_ACCEPT: 'text/plain' })
|
||||||
end
|
end
|
||||||
|
|
||||||
let(:mock_request_with_unhandle_headers) do
|
let(:mock_request_with_unhandled_headers) do
|
||||||
OpenStruct.new(env: {
|
instance_double(Rack::Request, env: {
|
||||||
HTTP_REFERER: 'http://example.com',
|
HTTP_REFERER: 'http://example.com',
|
||||||
"PATH_INFO"=>"/api/v1/users"
|
'PATH_INFO' => '/api/v1/users'
|
||||||
})
|
})
|
||||||
end
|
end
|
||||||
|
|
||||||
let(:mock_request_with_long_headers) do
|
let(:mock_request_with_long_headers) do
|
||||||
OpenStruct.new(env: {
|
instance_double(Rack::Request, env: {
|
||||||
HTTP_REFERER: 'http://example.com',
|
HTTP_REFERER: 'http://example.com',
|
||||||
HTTP_USER_AGENT: "Mozilla/5.0"
|
HTTP_USER_AGENT: 'Mozilla/5.0'
|
||||||
})
|
})
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'strips HTTP_ from the parameter' do
|
it 'strips HTTP_ from the parameter' do
|
||||||
expect(subject.parameters(mock_request, nil)).to eq({
|
expect(subject.parameters(mock_request, nil)).to eq(
|
||||||
headers: {'Referer' => 'http://example.com', 'Accept' => 'text/plain'}
|
{
|
||||||
})
|
headers: { 'Referer' => 'http://example.com', 'Accept' => 'text/plain' }
|
||||||
|
}
|
||||||
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'only handle things which start with HTTP_' do
|
it 'only handle things which start with HTTP_' do
|
||||||
expect(subject.parameters(mock_request_with_unhandle_headers, nil)).to eq({
|
expect(subject.parameters(mock_request_with_unhandled_headers, nil)).to eq(
|
||||||
headers: {'Referer' => 'http://example.com' }
|
{
|
||||||
})
|
headers: { 'Referer' => 'http://example.com' }
|
||||||
|
}
|
||||||
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'substitutes _ with -' do
|
it 'substitutes _ with -' do
|
||||||
expect(subject.parameters(mock_request_with_long_headers, nil)).to eq({
|
expect(subject.parameters(mock_request_with_long_headers, nil)).to eq(
|
||||||
headers: {'Referer' => 'http://example.com', 'User-Agent' => 'Mozilla/5.0' }
|
{
|
||||||
})
|
headers: { 'Referer' => 'http://example.com', 'User-Agent' => 'Mozilla/5.0' }
|
||||||
|
}
|
||||||
|
)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -1,28 +1,23 @@
|
||||||
require 'spec_helper'
|
require 'spec_helper'
|
||||||
require 'ostruct'
|
|
||||||
|
|
||||||
describe GrapeLogging::Loggers::Response do
|
describe GrapeLogging::Loggers::Response do
|
||||||
context 'with a parseable JSON body' do
|
context 'with a parseable JSON body' do
|
||||||
let(:response) do
|
let(:response) do
|
||||||
OpenStruct.new(body: [%q{{"one": "two", "three": {"four": 5}}}])
|
instance_double(Rack::Request, body: [{ one: 'two', three: { four: 5 } }])
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'returns an array of parseable JSON objects' do
|
it 'returns an array of parsed JSON objects' do
|
||||||
expect(subject.parameters(nil, response)).to eq({
|
expect(subject.parameters(nil, response)).to eq({ response: [response.body.first] })
|
||||||
response: [response.body.first.dup]
|
|
||||||
})
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'with a body that is not parseable JSON' do
|
context 'with a body that is not parseable JSON' do
|
||||||
let(:response) do
|
let(:response) do
|
||||||
OpenStruct.new(body: "this is a body")
|
instance_double(Rack::Request, body: 'this is a body')
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'just returns the body' do
|
it 'just returns the body' do
|
||||||
expect(subject.parameters(nil, response)).to eq({
|
expect(subject.parameters(nil, response)).to eq({ response: response.body })
|
||||||
response: response.body.dup
|
|
||||||
})
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -2,11 +2,12 @@ require 'spec_helper'
|
||||||
require 'rack'
|
require 'rack'
|
||||||
|
|
||||||
describe GrapeLogging::Middleware::RequestLogger do
|
describe GrapeLogging::Middleware::RequestLogger do
|
||||||
let(:subject) { request.send(request_method, path) }
|
let(:env) { { 'action_dispatch.request_id' => 'request-abc123' } }
|
||||||
let(:app) { proc{ [status, {} , ['response body']] } }
|
let(:subject) { request.send(request_method, path, env) }
|
||||||
let(:stack) { described_class.new app, options }
|
let(:app) { proc { [status, {}, ['response body']] } }
|
||||||
|
let(:stack) { described_class.new app, **options }
|
||||||
let(:request) { Rack::MockRequest.new(stack) }
|
let(:request) { Rack::MockRequest.new(stack) }
|
||||||
let(:options) { {include: [], logger: logger} }
|
let(:options) { { include: [], logger: logger } }
|
||||||
let(:logger) { double('logger') }
|
let(:logger) { double('logger') }
|
||||||
let(:path) { '/' }
|
let(:path) { '/' }
|
||||||
let(:request_method) { 'get' }
|
let(:request_method) { 'get' }
|
||||||
|
|
@ -18,6 +19,7 @@ describe GrapeLogging::Middleware::RequestLogger do
|
||||||
expect(arguments[:method]).to eq 'GET'
|
expect(arguments[:method]).to eq 'GET'
|
||||||
expect(arguments[:params]).to be_empty
|
expect(arguments[:params]).to be_empty
|
||||||
expect(arguments[:host]).to eq 'example.org'
|
expect(arguments[:host]).to eq 'example.org'
|
||||||
|
expect(arguments[:request_id]).to eq 'request-abc123'
|
||||||
expect(arguments).to have_key :time
|
expect(arguments).to have_key :time
|
||||||
expect(arguments[:time]).to have_key :total
|
expect(arguments[:time]).to have_key :total
|
||||||
expect(arguments[:time]).to have_key :db
|
expect(arguments[:time]).to have_key :db
|
||||||
|
|
@ -27,7 +29,7 @@ describe GrapeLogging::Middleware::RequestLogger do
|
||||||
end
|
end
|
||||||
|
|
||||||
[301, 404, 500].each do |the_status|
|
[301, 404, 500].each do |the_status|
|
||||||
context "when the respnse status is #{the_status}" do
|
context "when the response status is #{the_status}" do
|
||||||
let(:status) { the_status }
|
let(:status) { the_status }
|
||||||
it 'should log the correct status code' do
|
it 'should log the correct status code' do
|
||||||
expect(logger).to receive('info') do |arguments|
|
expect(logger).to receive('info') do |arguments|
|
||||||
|
|
@ -49,7 +51,7 @@ describe GrapeLogging::Middleware::RequestLogger do
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'with a nil response' do
|
context 'with a nil response' do
|
||||||
let(:app) { proc{ [500, {} , nil] } }
|
let(:app) { proc { [500, {}, nil] } }
|
||||||
it 'should log "fail" instead of a status' do
|
it 'should log "fail" instead of a status' do
|
||||||
expect(Rack::MockResponse).to receive(:new) { nil }
|
expect(Rack::MockResponse).to receive(:new) { nil }
|
||||||
expect(logger).to receive('info') do |arguments|
|
expect(logger).to receive('info') do |arguments|
|
||||||
|
|
@ -64,7 +66,7 @@ describe GrapeLogging::Middleware::RequestLogger do
|
||||||
options[:include] << GrapeLogging::Loggers::RequestHeaders.new
|
options[:include] << GrapeLogging::Loggers::RequestHeaders.new
|
||||||
options[:include] << GrapeLogging::Loggers::ClientEnv.new
|
options[:include] << GrapeLogging::Loggers::ClientEnv.new
|
||||||
options[:include] << GrapeLogging::Loggers::Response.new
|
options[:include] << GrapeLogging::Loggers::Response.new
|
||||||
options[:include] << GrapeLogging::Loggers::FilterParameters.new(["replace_me"])
|
options[:include] << GrapeLogging::Loggers::FilterParameters.new(['replace_me'])
|
||||||
end
|
end
|
||||||
|
|
||||||
%w[get put post delete options head patch].each do |the_method|
|
%w[get put post delete options head patch].each do |the_method|
|
||||||
|
|
@ -84,9 +86,9 @@ describe GrapeLogging::Middleware::RequestLogger do
|
||||||
it 'should filter parameters in the log' do
|
it 'should filter parameters in the log' do
|
||||||
expect(logger).to receive('info') do |arguments|
|
expect(logger).to receive('info') do |arguments|
|
||||||
expect(arguments[:params]).to eq(
|
expect(arguments[:params]).to eq(
|
||||||
"replace_me" => '[FILTERED]',
|
'replace_me' => '[FILTERED]',
|
||||||
"replace_me_too" => '[FILTERED]',
|
'replace_me_too' => '[FILTERED]',
|
||||||
"cant_touch_this" => 'should see'
|
'cant_touch_this' => 'should see'
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
parameters = {
|
parameters = {
|
||||||
|
|
|
||||||
|
|
@ -33,57 +33,55 @@ RSpec.configure do |config|
|
||||||
# triggering implicit auto-inclusion in groups with matching metadata.
|
# triggering implicit auto-inclusion in groups with matching metadata.
|
||||||
config.shared_context_metadata_behavior = :apply_to_host_groups
|
config.shared_context_metadata_behavior = :apply_to_host_groups
|
||||||
|
|
||||||
# The settings below are suggested to provide a good initial experience
|
# The settings below are suggested to provide a good initial experience
|
||||||
# with RSpec, but feel free to customize to your heart's content.
|
# with RSpec, but feel free to customize to your heart's content.
|
||||||
=begin
|
# # This allows you to limit a spec run to individual examples or groups
|
||||||
# This allows you to limit a spec run to individual examples or groups
|
# # you care about by tagging them with `:focus` metadata. When nothing
|
||||||
# you care about by tagging them with `:focus` metadata. When nothing
|
# # is tagged with `:focus`, all examples get run. RSpec also provides
|
||||||
# is tagged with `:focus`, all examples get run. RSpec also provides
|
# # aliases for `it`, `describe`, and `context` that include `:focus`
|
||||||
# aliases for `it`, `describe`, and `context` that include `:focus`
|
# # metadata: `fit`, `fdescribe` and `fcontext`, respectively.
|
||||||
# metadata: `fit`, `fdescribe` and `fcontext`, respectively.
|
# config.filter_run_when_matching :focus
|
||||||
config.filter_run_when_matching :focus
|
#
|
||||||
|
# # Allows RSpec to persist some state between runs in order to support
|
||||||
# Allows RSpec to persist some state between runs in order to support
|
# # the `--only-failures` and `--next-failure` CLI options. We recommend
|
||||||
# the `--only-failures` and `--next-failure` CLI options. We recommend
|
# # you configure your source control system to ignore this file.
|
||||||
# you configure your source control system to ignore this file.
|
# config.example_status_persistence_file_path = "spec/examples.txt"
|
||||||
config.example_status_persistence_file_path = "spec/examples.txt"
|
#
|
||||||
|
# # Limits the available syntax to the non-monkey patched syntax that is
|
||||||
# Limits the available syntax to the non-monkey patched syntax that is
|
# # recommended. For more details, see:
|
||||||
# recommended. For more details, see:
|
# # - http://rspec.info/blog/2012/06/rspecs-new-expectation-syntax/
|
||||||
# - http://rspec.info/blog/2012/06/rspecs-new-expectation-syntax/
|
# # - http://www.teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/
|
||||||
# - http://www.teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/
|
# # - http://rspec.info/blog/2014/05/notable-changes-in-rspec-3/#zero-monkey-patching-mode
|
||||||
# - http://rspec.info/blog/2014/05/notable-changes-in-rspec-3/#zero-monkey-patching-mode
|
# config.disable_monkey_patching!
|
||||||
config.disable_monkey_patching!
|
#
|
||||||
|
# # This setting enables warnings. It's recommended, but in some cases may
|
||||||
# This setting enables warnings. It's recommended, but in some cases may
|
# # be too noisy due to issues in dependencies.
|
||||||
# be too noisy due to issues in dependencies.
|
# config.warnings = true
|
||||||
config.warnings = true
|
#
|
||||||
|
# # Many RSpec users commonly either run the entire suite or an individual
|
||||||
# Many RSpec users commonly either run the entire suite or an individual
|
# # file, and it's useful to allow more verbose output when running an
|
||||||
# file, and it's useful to allow more verbose output when running an
|
# # individual spec file.
|
||||||
# individual spec file.
|
# if config.files_to_run.one?
|
||||||
if config.files_to_run.one?
|
# # Use the documentation formatter for detailed output,
|
||||||
# Use the documentation formatter for detailed output,
|
# # unless a formatter has already been configured
|
||||||
# unless a formatter has already been configured
|
# # (e.g. via a command-line flag).
|
||||||
# (e.g. via a command-line flag).
|
# config.default_formatter = 'doc'
|
||||||
config.default_formatter = 'doc'
|
# end
|
||||||
end
|
#
|
||||||
|
# # Print the 10 slowest examples and example groups at the
|
||||||
# Print the 10 slowest examples and example groups at the
|
# # end of the spec run, to help surface which specs are running
|
||||||
# end of the spec run, to help surface which specs are running
|
# # particularly slow.
|
||||||
# particularly slow.
|
# config.profile_examples = 10
|
||||||
config.profile_examples = 10
|
#
|
||||||
|
# # Run specs in random order to surface order dependencies. If you find an
|
||||||
# Run specs in random order to surface order dependencies. If you find an
|
# # order dependency and want to debug it, you can fix the order by providing
|
||||||
# order dependency and want to debug it, you can fix the order by providing
|
# # the seed, which is printed after each run.
|
||||||
# the seed, which is printed after each run.
|
# # --seed 1234
|
||||||
# --seed 1234
|
# config.order = :random
|
||||||
config.order = :random
|
#
|
||||||
|
# # Seed global randomization in this process using the `--seed` CLI option.
|
||||||
# Seed global randomization in this process using the `--seed` CLI option.
|
# # Setting this allows you to use `--seed` to deterministically reproduce
|
||||||
# Setting this allows you to use `--seed` to deterministically reproduce
|
# # test failures related to randomization by passing the same `--seed` value
|
||||||
# test failures related to randomization by passing the same `--seed` value
|
# # as the one that triggered the failure.
|
||||||
# as the one that triggered the failure.
|
# Kernel.srand config.seed
|
||||||
Kernel.srand config.seed
|
|
||||||
=end
|
|
||||||
end
|
end
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue