Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add custom Azure logger #17228

Merged
merged 1 commit into from
Apr 3, 2018
Merged

Add custom Azure logger #17228

merged 1 commit into from
Apr 3, 2018

Conversation

djberg96
Copy link
Contributor

@djberg96 djberg96 commented Mar 29, 2018

Because of quirks of the rest-client library (see rest-client/rest-client#34), the $azure_log does not include timestamp information (see ManageIQ/manageiq-providers-azure#177). In addition, the current log includes potentially sensitive information that should be filtered, such as bearer token information. This information also happens to be large, resulting in a rather large log file after a relatively short amount of time.

Applying a custom filter to the logger requires a special subclass, as the formatter is not directly accessible from the $azure_log once created. This subclass sets the formatter so that not only adds the timestamp information, it also filters out Bearer token strings (which are passed along with most Azure REST API requests), SharedKey token strings (used to access Azure's unmanaged storage accounts) and client_id strings (used when initially generating the Bearer token).

Each Bearer token is over 1300 bytes, so this would not only filter potentially sensitive information, it reduces the size of each logged request by over 1k per request.

To test: Add or refresh an Azure cloud provider, and watch the azure.log file.

WIP for now until I can figure out why it always seems to set the severity to WARN, and can add some real specs.

Added some specs. The WARN is because that's the default setting for the Azure provider.

@djberg96
Copy link
Contributor Author

@NickLaMuro @Fryguy How's that look?

@miq-bot miq-bot added the wip label Mar 29, 2018
@djberg96 djberg96 changed the title [WIP] Add custom Azure logger Add custom Azure logger Mar 29, 2018
@miq-bot miq-bot removed the wip label Mar 29, 2018
@NickLaMuro
Copy link
Member

Seems reasonable to me. Not sure if we want to push having specialized loggers in the main repo, but I think maybe canning that discussion for now is the best choice and moving forward with this.

That said, I think the bot has some suggestions for you 😉

@djberg96
Copy link
Contributor Author

djberg96 commented Apr 2, 2018

@NickLaMuro Trying to use utc just causes me grief. I don't understand the current failures, either:

expected "[2018-04-02 16:20:59 +0000] - INFO -- : Hello\n" to match "2018-04-02 16:20:59 +0000"

Note that these specs pass locally.

msg = msg.strip
log(level, msg)
msg.size
end
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this necessary? A VMDBLogger is a Logger, which already has the << method defined as you have done here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure why, but it won't work without it. I assume it's a rest-client issue.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What kind of error? I just tried << on a VMDBLogger and it works.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ohhh, I see... << "works", but doesn't write out the timestamp, which is the problem in the first place. I'm wondering if this should just be implemented on the underlying VMDBLogger class instead. @NickLaMuro @bdunne thoughts?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm wondering if this should just be implemented on the underlying VMDBLogger class instead.

I don't know, seems like a bad idea. The whole point of Logger#<< is to print without formatting:

https://github.com/ruby/ruby/blob/trunk/lib/logger.rb#L477-L483

I think it is stupid for rest-client to log via <<, so I think doing this is a targeted class makes more sense. We only want this with loggers where this is a problem (i.e., ones that have to hook into rest-client), and not for every logger in MIQ, because the original behavior of #<< might be desired in some other circumstance.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bdunne Yes, we have. Take a look at the issue tracker for rest-client. Unfortunately, the project is in poor health.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have been looking into replacing rest-client where we can (since a couple of dependencies for it our ones we own). That said, it is more a labor of love, and not something on the "official agenda".

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@NickLaMuro I'm desperately trying to get azure-armrest switched over to Excon, but it's a lot of work. I should probably make a separate port where I don't try to refactor anything as I go, and just do a straight port to get it working.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@NickLaMuro I actually thinking moving off of rest-client should start getting prioritized a bit higher the longer that rest-client languishes. I think Excon and Faraday are the two best options at this point.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was just going to use net/http where the additions of provided by other libs aren't really necessary.

:neckbeard:

@formatter = proc do |severity, datetime, _progname, msg|
msg = msg.sub(/Bearer(.*?)\"/, 'Bearer [FILTERED] "')
msg = msg.sub(/SharedKey(.*?)\"/, 'SharedKey [FILTERED] "')
msg = msg.sub(/client_secret=(.*?)&/, "client_secret=[FILTERED]&")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 👍 👍

def initialize(*loggers)
super

@datetime_format = '%Y-%m-%d %H:%M:%S'
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why an alternate datetime_format? Doesn't that make the log messages inconsistent with other VMDBLogger instances?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, I'll remove it.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If for some reason you don't want my_logger.datetime_format to return `nil, you can use the string I provided in the following comment:

#17228 (comment)

Which is what is defaulted in ruby:

https://github.com/ruby/ruby/blob/3be45505/lib/logger.rb#L603-L605

But it does a poor job of making it a constant... which makes me a bit 😡y

msg = msg.sub(/Bearer(.*?)\"/, 'Bearer [FILTERED] "')
msg = msg.sub(/SharedKey(.*?)\"/, 'SharedKey [FILTERED] "')
msg = msg.sub(/client_secret=(.*?)&/, "client_secret=[FILTERED]&")
"[#{datetime}] - #{severity} -- : #{msg}\n"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👎 I don't see why the log message should be completely different from other log messages.

Copy link
Member

@NickLaMuro NickLaMuro Apr 2, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does it maybe make sense to extend the the VMDBLogger::Formatter#call method here instead then, so we are keeping the same format, but making sure to sub what is needed?

module Vmdb::Loggers
  class AzureLogger < VMDBLogger
    def initialize(*loggers)
      super

      # pulled from Ruby's `Logger::Formatter`, which is what it defaults to when it is `nil`
      @datetime_format = "%Y-%m-%dT%H:%M:%S.%6N "
      @formatter       = Vmdb::Loggers::AzureLogger::Formatter.new
    end

    # ...

    class Formatter < VMDBLogger::Formatter
      def call(severity, datetime, _progname, msg)
        msg = msg.sub(/Bearer(.*?)\"/, 'Bearer [FILTERED] "')
        msg = msg.sub(/SharedKey(.*?)\"/, 'SharedKey [FILTERED] "')
        msg = msg.sub(/client_secret=(.*?)&/, "client_secret=[FILTERED]&")
        super(severity, datetime, _progname, msg)
      end
    end
  end
end

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know how to filter the message without having to also specify the format explicitly with a logger instance. Is there a message format I can easily use?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@djberg96 I think you were responding to what @Fryguy was asking not me (posted at roughly the same time it seems). I think what I have supplied would do just that.

@Fryguy
Copy link
Member

Fryguy commented Apr 2, 2018

This formatter loses all of the debug information we need like pid, tid, and not to mention that the current format likely won't work in containers mode at all.

@NickLaMuro
Copy link
Member

NickLaMuro commented Apr 2, 2018

This formatter loses all of the debug information we need like pid, tid, and not to mention that the current format likely won't work in containers mode at all.

@Fryguy Good points here in your review and you did a much better job than I did at catching these points...

But... this won't affect containers since it would just get tossed to the lib/vmdb/loggers/container_logger.rb anyway, which will have it's own formatter. That said, that means in the containers the token and other stuff won't be filtered, so that is something we maybe should consider.

@Fryguy
Copy link
Member

Fryguy commented Apr 2, 2018

@NickLaMuro Oh good catch...for some reason I though the json was generated from the log message.

@Fryguy
Copy link
Member

Fryguy commented Apr 2, 2018

ContainerLogger is actually a really good example of creating a custom formatter that's based on VMDBLogger::Formatter the way @NickLaMuro did in the snippet above.

@djberg96
Copy link
Contributor Author

djberg96 commented Apr 2, 2018

@Fryguy Alright, reworked it using @NickLaMuro's Formatter subclass.

Filter SharedKey and client_secret, add custom << method.

Added some spaces back into replacement strings, and added some specs.

Reworked to subclass Formatter.
@miq-bot
Copy link
Member

miq-bot commented Apr 3, 2018

Checked commit https://github.com/djberg96/manageiq/commit/dcdc4d60a6a65046321ba1111b772285d360f174 with ruby 2.3.3, rubocop 0.52.1, haml-lint 0.20.0, and yamllint 1.10.0
3 files checked, 0 offenses detected
Everything looks fine. ⭐

Copy link
Member

@NickLaMuro NickLaMuro left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me.

@Fryguy
Copy link
Member

Fryguy commented Apr 3, 2018

I am good with this. Ultimately, I'd like this to be pluggable, but we should just add it to the list : #14840.

@Fryguy Fryguy merged commit 2652592 into ManageIQ:master Apr 3, 2018
@Fryguy Fryguy added this to the Sprint 83 Ending Apr 9, 2018 milestone Apr 3, 2018
@Fryguy Fryguy self-assigned this Apr 3, 2018
@Fryguy Fryguy modified the milestones: Sprint 83 Ending Apr 9, 2018, Roadmap Apr 3, 2018
@djberg96
Copy link
Contributor Author

@simaishi Please backport this to the G release: https://bugzilla.redhat.com/show_bug.cgi?id=1640718

@djberg96
Copy link
Contributor Author

@miq-bot add_label gaprindashvili/yes

@simaishi
Copy link
Contributor

@djberg96 I can't backport PR to Gaprindashvili branch unless BZ is approved for a particular G-release by bug triage...

@djberg96
Copy link
Contributor Author

@simaishi I think it's been approved now. :)

@simaishi
Copy link
Contributor

@djberg96 It's still not approved for G-branch...

"Approved" BZs will have "Target Release" set to a particular release (e.g. 5.9.6), and "blocker" flag set. Since the BZ's target release was changed, this will be included only in Hammer and later builds.

@djberg96
Copy link
Contributor Author

@dmetzger57 I need this approved for G branch or I can't close the BZ.

@simaishi
Copy link
Contributor

@djberg96 I already took care of the BZ.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants