Bandwidth summary per server - ruby

I am trying to get the bandwidth data for all the softlayer servers under my account.
Thanks to account_servers.rb I am able to get the server id for all the servers. Now I would like to get the Bandwidth used by the servers for a particular time frame. The data that I am interested is
http://sldn.softlayer.com/reference/datatypes/SoftLayer_Metric_Tracking_Object_Bandwidth_Summary
.
I tried to get information using softlayer_client.service_named("Metric_Tracking_Object_Bandwidth_Summary"). Unfortunately I am not able to get the details.
I did find a java code, but I am interested in ruby code. Can someone please guide me to get the server bandwith summary?
Getting bandWidth data in SL

Please, try the following Ruby examples:
require 'rubygems'
require 'softlayer_api'
server_id = 11498369
# Your SoftLayer API username.
SL_API_USERNAME = 'set me'
# Your SoftLayer API key.
SL_API_KEY = 'set me'
softlayer_client = SoftLayer::Client.new(:username => SL_API_USERNAME,
:api_key => SL_API_KEY)
vsi_service = softlayer_client.service_named('SoftLayer_Virtual_Guest')
metric_tracking_object_id = vsi_service.object_with_id(server_id).getMetricTrackingObjectId
metric_service = softlayer_client.service_named('SoftLayer_Metric_Tracking_Object')
service_ref = metric_service.object_with_id(metric_tracking_object_id)
begin
object_template = [{
'keyName' => 'PUBLICOUT',
'summaryType' => 'sum'
}]
result = service_ref.getSummaryData('2016-03-29T00:00:00','2016-03-30T00:00:00',object_template,600)
puts result.inspect
rescue => e
puts 'Error when executing the script...'
$stdout.print(e.inspect)
end
References:
SoftLayer_Metric_Tracking_Object::getSummaryData
SoftLayer_Virtual_Guest::getMetricTrackingObjectId
Second example using SoftLayer_Virtual_Gues::getBandwidthDataByDate:
require 'rubygems'
require 'softlayer_api'
require 'pp'
require 'date'
# Set the server id that you wish to get Bandwidth information.
server_id = 11498369
softlayer_client = SoftLayer::Client.new(:username => 'set me',
:api_key => 'set me')
server = SoftLayer::VirtualServer.server_with_id(server_id, :client => softlayer_client)
get_bandwidth_data_by_date = server.service.getBandwidthDataByDate('2016-03-29T00:00:00','2016-03-30T00:00:00','public')
pp('getBandwidthDataByDate: ', get_bandwidth_data_by_date)
References:
SoftLayer_Virtual_Guest::getBandwidthDataByDate

Disclamer: I created my own Ruby SoftLayer client, you can check it at http://github.com/zertico/softlayer specially for situations like this one where you want to access some specific data (and I'm not SoftLayer staff ;) )
If you'd like to give it a try the code that solves your problem is
ps: I'm considering you are manipulating a SoftLayer_Hardware_Server, right?
hardware = Softlayer::Hardware::Server.find(123)
hardware.get_current_bandwidth_summary
mask = 'mask[currentBandwidthSummary]'
hardware = Softlayer::Hardware::Server.mask(mask).find(123)
hardware.current_bandwidth_summary
You will access a ruby object like this one:
=> #<Softlayer::Metric::Tracking::Object::Bandwidth::Summary:0x007ff74b683540
#allocation_amount="1234",
#allocation_id=111111,
#amount_out="12.34567",
#average_daily_usage="1.23",
#currently_over_allocation_flag=0,
#id=1111111,
#outbound_bandwidth_amount="123.45678",
#projected_bandwidth_usage="123.45",
#projected_over_allocation_flag=0>
Hope it can helps you, comment if you have any doubt about the client usage

Related

object_mask not working for Ruby SoftLayer API call SoftLayer::BareMetalServer.find_servers

I'm having trouble getting an object_mask applied to the data I'm retrieving. Here is a snippet of what I'm doing:
client = SoftLayer::Client.new(<...hidden...>)
<BREAK>
if (item["hostName"])
machines = SoftLayer::BareMetalServer.find_servers({ :client => client, :hostname => item["hostName"], :object_mask => "[id,hostname,tagReferences]"})
machines.each do |machine|
pp machine
end
end
When I print "machine" it is still printing all the fields. Thank you in advance for any help.
$ ruby -v
ruby 2.1.2p95 (2014-05-08 revision 45877) [x86_64-linux]
I was not able to get specific items using masks with “BareMetalServer.find_servers”, but below is another ruby example that may help you:
require 'rubygems'
require 'softlayer_api'
# Your SoftLayer API username.
SL_API_USERNAME = 'set me'
# Your SoftLayer API key.
SL_API_KEY = 'set me'
softlayer_client = SoftLayer::Client.new(:username => SL_API_USERNAME,
:api_key => SL_API_KEY)
account_service = softlayer_client.service_named('SoftLayer_Account')
# Create an object mask to get more information than by default
mask = 'mask[id,hostname]'
begin
result = account_service.object_mask(mask).getHardware
puts 'Process finished successfully'
p result
rescue Exception => e
raise e
end
References:
http://sldn.softlayer.com/reference/services/SoftLayer_Account/getHardware
https://softlayer.github.io/ruby/token_auth/
https://softlayer.github.io/ruby/find_my_vms/
https://softlayer.github.io/ruby/
https://www.omniref.com/ruby/gems/softlayer_api/2.1.0
https://github.com/softlayer/softlayer-ruby/blob/master/lib/softlayer/BareMetalServer.rb
Currently the ojectMask for the method find_servers does not limit the fields, it adds the fields of your object mask to the result.
If you need to limit the fields, you could use the use "map" to create an array with just the fields you are interested in.

Timeout error when using SoftLayer Ruby API

I am trying to get simple billing information using the script below. The script fails with a timeout error. Can someone help me figure out the problem?
require 'rubygems'
require 'softlayer_api'
require 'pp'
billing = SoftLayer::Service.new("SoftLayer_Account",:username => "USER", :api_key => "KEY", :timeout => 99999)
object_mask = "mask[orderItem[order[userRecord[username]]], invoiceItem[totalRecurringAmount]]"
user_bill= billing.object_mask(object_mask).getNextInvoiceTopLevelBillingItems
pp user_bill
If the API is responding normally for other calls this is most likely caused by the amount of data being requested. The SLAPI will often time out when more information than it can handle is requested.
You can avoid this by using result limits or specifying only the specific properties you want.
When you reference a relational property by default the entire set of local properties is returned. Even when passing through one property to another. The above call would return the entire set of billing items with their associated local properties, all of the local properties for the order(which is being pulled in for each order item redundantly), and the entire invoice item with totalRecurringAmount.
By specifying id at each level you can reduce the amount of data returned:
mask[
orderItem[
id,
order[
id,
userRecord[username]
]
],
invoiceItem[
id,
totalRecurringAmount
]
]
However, at some number of devices/products the call will start to become overloaded again and it will be necessary to paginate the results and process them in batch.
http://sldn.softlayer.com/blog/phil/How-Solve-Error-fetching-http-headers
Probably your account has many billing items and it causes the exception, take a look the following article:
http://sldn.softlayer.com/blog/phil/How-Solve-Error-fetching-http-headers
I can recommend to use resultLimits, in order to avoid the exception, take a look the following Ruby script:
# Get Next Invoice Top Level Billing Items
#
# This script retrieves the billing items that will be on an account's next invoice
#
# Important manual pages:
# http://sldn.softlayer.com/reference/services/SoftLayer_Account/getNextInvoiceTopLevelBillingItems
# http://sldn.softlayer.com/reference/datatypes/SoftLayer_Billing_Item
#
# #license <http://sldn.softlayer.com/article/License>
# #author SoftLayer Technologies, Inc. <sldn#softlayer.com>
require 'rubygems'
require 'softlayer_api'
require 'pp'
# Helper function to fetch through all results from SoftLayer api
# using small page sizes and sleeping before every new page fetch.
def fetch_all(service, method)
records = []; offset = 0; limit = 1000
loop do
results = service.result_limit(offset, limit).send(method)
records += results
break if results.size < limit
offset += limit
sleep 3
end
records
end
# Creating the account service.
billing = SoftLayer::Service.new("SoftLayer_Account", :username => "set me", :api_key => "set me", :timeout => 200)
# object mask
object_mask = "mask[orderItem[order[userRecord[username]]], invoiceItem[totalRecurringAmount]]"
begin
# Calling helper function to get all the result for getNextInvoiceTopLevelBillingItems method
user_bill = fetch_all(billing.object_mask(object_mask), :getNextInvoiceTopLevelBillingItems)
# Print
pp user_bill
rescue StandardError => exception
puts "Error: #{exception}"
end
I hope it helps

Mongodb not inserting Ruby time.new consistantly on Heroku

Built a small app to grab Tweets from political candidates for the upcoming election. Using Ruby, Twitterstream, Mongodb and Heroku.
The time is being inserted into the database inconsistantly. Sometimes it works, sometimes it doesn't. Is this my code, Heroku or Mongodb (Mongohq). I have a support question in.
Working
{
_id: ObjectId("52556b5bd2d9530002000002"),
time: ISODate("2013-10-09T14:42:35.044Z"),
user: "Blondetigressnc",
userid: 1342776674,
tweet: "RT #GovBrewer: Mr. President #BarackObama, reopen America’s National Parks or let the states do it. #GrandCanyon #Lead http://t.co/kkPKt9B7…",
statusid: "387951226866110464"
}
Not working
{
_id: ObjectId("52556c2454d4ad0002000016"),
user: "PeterMcC66",
userid: 1729065984,
tweet: "#GovBrewer #Blondetigressnc #BarackObama Time to impeach surely?",
statusid: "387952072223506432"
}
Seems random. See anything wrong or stupid in my code?
require 'rubygems'
require 'tweetstream'
require 'mongo'
# user ids
users = 'list of Twitter user ids here'
# connect to stream
TweetStream.configure do |config|
config.consumer_key = ENV['T_KEY']
config.consumer_secret = ENV['T_SECRET']
config.oauth_token = ENV['T_TOKEN']
config.oauth_token_secret = ENV['T_TOKEN_SECRET']
config.auth_method = :oauth
end
# connection to database
if ENV['MONGOHQ_URL']
uri = URI.parse(ENV['MONGOHQ_URL'])
conn = Mongo::Connection.from_uri(ENV['MONGOHQ_URL'])
DB = conn.db(uri.path.gsub(/^\//, ''))
else
DB = Mongo::Connection.new.db("tweetsDB")
end
# creation of collections
tweets = DB.create_collection("tweets")
deleted = DB.create_collection("deleted-tweets")
#client = TweetStream::Client.new
#client.on_delete do | status_id, user_id |
puts "#{status_id}"
timenow = Time.new
id = status_id.to_s
deleted.insert({ :time => timenow, :user_id => user_id, :statusid => id })
end
#client.follow(users) do |status|
puts "[#{status.user.screen_name}] #{status.text}"
timenow = Time.new
id = status.id
tweets.insert({ :time => timenow, :user => status.user.screen_name, :userid => status.user.id, :tweet => status.text, :statusid => id.to_s })
end
The issue is that you need to use a UTC time, not your local timezone. This is not a MongoDB or a Ruby driver issue, its a constraint of the BSON spec and the ISODate BSON type.
http://docs.mongodb.org/manual/reference/bson-types/#date
http://bsonspec.org/#/specification
Also, just a good practice though.
General word of advice: Use UTC on the back-end of whatever you're building always anyway, regardless of what datastore you're using (not a MongoDB specific thing). This is especially true if this data is something you want to query on directly.
If you need to convert to a local timezone, its best to handle that when you display or output the data rather than trying to manage that elsewhere. Some of the most fantastic bugs I've ever seen were related to inconsistent handling of timezones in the persistence layer of the application.
Keep those times consistent on the back-and, deal with local timezone conversion when in your application and life will be much easier for you.
Here is an examples of how to work with times in MongoDB using Ruby:
require 'time' # required for ISO-8601
require 'mongo'
include Mongo
client = MongoClient.new
coll = client['example_database']['example_collection']
coll.insert({ 'updated_at' => Time.now.utc })
doc = coll.find_one()
doc['updated_it'].is_a?(Time) #=> true
doc['updated_at'].to_s #=> "2013-10-07 22:43:52 UTC"
doc['updated_at'].iso8601 #=> "2013-10-07T22:43:52Z"
doc['updated_at'].strftime("updated at %m/%d/%Y") #=> "updated at 10/07/2013"
I keep a gist of this available here:
https://gist.github.com/brandonblack/6876374

how to use Xively API Library on Ruby?

i'm triyng to upload some data to xively from ruby, i did install all the gems and this test code runs ok, but nothing changes in the xively graph of my device.
This small code was isolated from the fragment of a bigger code that works fine, and post data to my server with an interface written in php, but now i want to use xively to log the data.
I did remove my personal data from this code, API_KEY, Feed number and feed Name.
#!/usr/bin/ruby
require 'rubygems'
require 'json'
require 'xively-rb'
##Creating the xively client instance
API_KEY = "MY_API_KEY_WAS_HERE"
client = Xively::Client.new(API_KEY)
#on an endless loop
while true
#n is a random float between 0 y 1
n = rand()
##Creating datapoint and sendig it to xively
puts "Creating datapoint "+Time.now.to_s+", "+n.to_s+" and sending it to xively"
datapoint = Xively::Datapoint.new(:at => Time.now, :value => n)
client.post('/api/v2/feeds/[number]/datastreams/[name]', :body => {:datapoints => [datapoint]}.to_json)
end
it would be nice to get an example on how to use that library, i didn't find any concise example.
(It's possible to find some silly errors in the code, if it's so, it's ok because im learning ruby at the moment, if it isn't critical just point it out briefly to not go offtopic, i will be happy to research and learn later)
im really looking forward for some answer, so thanks in advance.
I receive a solution that works from a classmate, it was in a post about Cosm the beta of what now is xively, what previously was pachube also.
we were about two weeks looking for something like this:
afulki.net more-on-ruby-and-cosm
#!/usr/bin/ruby
require 'xively-rb'
require 'json'
require 'rubygems'
class XivelyConnector
API_KEY = 'MY_API_KEY_HARD-CODED_HERE'
def initialize( xively_feed_id )
#feed_id = xively_feed_id
#xively_response = Xively::Client.get("/v2/feeds/#{#feed_id}.json", :headers => {"X-ApiKey" => API_KEY})
end
def post_polucion( sensor, polucion_en_mgxm3 )
return unless has_sensor? sensor
post_path = "/v2/feeds/#{#feed_id}/datastreams/#{sensor}/datapoints"
datapoint = Xively::Datapoint.new(:at => Time.now, :value => polucion_en_mgxm3.to_s )
response = Xively::Client.post(post_path,
:headers => {"X-ApiKey" => API_KEY},
:body => {:datapoints => [datapoint]}.to_json)
end
def has_sensor?( sensor )
#xively_response["datastreams"].index { |ds| ds["id"] == sensor }
end
end
Using that class:
#!/usr/bin/ruby
require 'rubygems'
require 'json'
require 'xively-rb'
require_relative 'XivelyConnector'
xively_connector = XivelyConnector.new( MY_FEED_ID_HERE )
while true
n = rand()
xively_connector.post_polucion 'Sensor-Asdf', n
sleep 1
end

Specifying the offset and limit in a Redmine REST API request with Ruby

I'm using the Ruby REST API for Redmine (here: http://www.redmine.org/projects/redmine/wiki/Rest_api_with_ruby). I need to be able to get all issues in a chunk of 100 at a time.
I know there is an options[:offset] and an options[:limit] that the method "api_offset_and_limit" is looking for.
How do I pass those options when I'm doing this? I tried putting them in the URL as GET options, but they didn't come through on the other end. The following gives me the first 25 issues, as I expect it to.
class Issue < ActiveResource::Base
self.site = 'http://redmine.server/'
self.user = 'foo'
self.password = 'bar'
end
# Retrieving issues
issues = Issue.find(:all)
I'm not familiar with the API, but the way you describe it, the following should work:
issues = Issue.find(:all, :params => {:offset => 0, :limit => 100})

Resources