Reputation: 223699
I'm looking for a method in pure Ruby of taking a timezone string such as "US/Eastern" and using it with a string representation of a timestamp to convert into a timestamp with timezone.
All I've found so far is strptime
which supports a short timezone name like "EST" or a timezone offset like "-0500", but not a full timezone string.
I need to be able to run this as part of a Logstash ruby filter. I have some JSON that contains timestamps with no timezone that looks like this:
{
"event": {
"created": "2021-02-15_11-26-29",
},
"Accounts": [
{
"Name": "operator",
"Caption": "SERVER\\operator",
"Domain": "SERVER",
"PasswordChangeable": "False",
"PasswordRequired": "True",
"PasswordExpires": "False",
"Disabled": "False",
"Lockout": "False",
"LocalAccount": "True",
"FullName": "operator",
"Status": "OK",
"LastLogon": "07/08/2020 2:14:13 PM"
},
...
]
}
For the event.created field I can just use a date
filter:
date {
match => [ "[event][created]", "yyyy-MM-dd_HH-mm-ss" ]
timezone => "${TIMEZONE}"
target => "[event][created]"
}
Where ${TIMEZONE}
is an environment variable holding the full timezone name, i.e. "US/Eastern". But for the Acounts.LastLogin field I can't use a date
filter because it resides in a list of variable length, so I have to resort to a ruby filter. The closest I was able to come was this:
ruby {
code => 'event.get("[Accounts]").each_index {|x|
tz = "-0500"
last_logon_str = event.get("[Accounts][#{x}][LastLogon]")
last_logon = DateTime.strptime(last_logon_str + " " + tz, "%m/%d/%Y %I:%M:%S %p %z")
event.set("[users][#{x}][last_logon]", last_logon.strftime("%Y-%m-%dT%H:%M:%S%z"))
}'
}
But of course this is using a hardcoded timezone offset and not the variable containing the full name.
The docs I looked at for the Time
object at https://ruby-doc.org/core-2.6/Time.html stated that a Time
object can be created using a timezone
:
Or a timezone object:
tz = timezone("Europe/Athens") # Eastern European Time, UTC+2 Time.new(2002, 10, 31, 2, 2, 2, tz) #=> 2002-10-31 02:02:02 +0200
Which I could then use to extract the offset, but I couldn't find a reference to timezone
anywhere.
What's the best way to handle this?
Upvotes: 1
Views: 344
Reputation: 4072
timezone is part of the TZInfo class. You need to require it. The following code
ruby {
code => '
require "tzinfo"
tz = TZInfo::Timezone.get(ENV["TIMEZONE"])
event.set("offset", tz.observed_utc_offset())
'
}
gets me "offset" => -18000,
when $TIMEZONE is "US/Eastern".
Upvotes: 1