class Fluent::AppdynamicsInput

Read trap messages as events in to fluentd

Public Class Methods

new() click to toggle source

Initialize and bring in dependencies

Calls superclass method
# File lib/fluent/plugin/in_appdynamics.rb, line 141
def initialize
  super
  require 'json'
  require 'yaml'
  require 'rest-client'
  require 'pp'
  # Add any other dependencies
end

Public Instance Methods

appdynamicsEnd(startTime,endTime) click to toggle source

@state_store = @state_file.nil? ? MemoryStateStore.new : StateStore.new(@state_file)

# File lib/fluent/plugin/in_appdynamics.rb, line 181
def appdynamicsEnd(startTime,endTime)
  # Setup URL Resource
  # Sample https://ep/controller/rest/applications/Prod/problems/healthrule-violations?time-range-type=BETWEEN_TIMES&output=JSON&start-time=1426270552990&end-time=1426270553000
  @url = @endpoint.to_s + "problems/healthrule-violations?time-range-type=BETWEEN_TIMES&output=JSON" + "&start-time=" + startTime.to_s + "&end-time=" + endTime.to_s
  $log.info @url
  RestClient::Resource.new(@url,@user+"@"+@account,@pass)
end
appdynamicsEntEnd(entityId) click to toggle source
# File lib/fluent/plugin/in_appdynamics.rb, line 189
def appdynamicsEntEnd(entityId)
          # Setup URL Resource
          # Sample https://ep/controller/rest/applications/Prod/nodes/81376?output=JSON
          @urlEntity = @endpoint.to_s + "nodes/" + entityId.to_s + "?output=JSON"
          $log.info @urlEntity
          RestClient::Resource.new(@urlEntity,@user+"@"+@account,@pass)
end
configure(conf) click to toggle source

Load internal and external configs

Calls superclass method
# File lib/fluent/plugin/in_appdynamics.rb, line 151
def configure(conf)
  super
  @conf = conf
  
  # State type is a must
  unless @state_type
    $log.warn "'state_type <redis/file/memory>' parameter is not set to a valid source."
    $log.warn "this parameter is highly recommended to save the last known good timestamp to resume event consuming"
    exit
  end

  # Define a handler that gets filled with
  unless @state_file
       $log.warn "'state_file PATH' parameter is not set to a valid source."
       log.warn "this parameter is highly recommended to save the last known good timestamp to resume event consuming"
       @state_store = MemoryStateStore.new
    else
       if (@state_type =~ /redis/)
           @state_store = RedisStateStore.new(@state_file, @tag)
       elsif (@state_type =~ /file/)
            @state_store = StateStore.new(@state_file, @tag)
       else
            $log.warn "Unknown state type. Need to handle this better"
            exit
       end
  end

  
  #@state_store = @state_file.nil? ? MemoryStateStore.new : StateStore.new(@state_file)

  def appdynamicsEnd(startTime,endTime)
    # Setup URL Resource
    # Sample https://ep/controller/rest/applications/Prod/problems/healthrule-violations?time-range-type=BETWEEN_TIMES&output=JSON&start-time=1426270552990&end-time=1426270553000
    @url = @endpoint.to_s + "problems/healthrule-violations?time-range-type=BETWEEN_TIMES&output=JSON" + "&start-time=" + startTime.to_s + "&end-time=" + endTime.to_s
    $log.info @url
    RestClient::Resource.new(@url,@user+"@"+@account,@pass)
  end

  def appdynamicsEntEnd(entityId)
            # Setup URL Resource
            # Sample https://ep/controller/rest/applications/Prod/nodes/81376?output=JSON
            @urlEntity = @endpoint.to_s + "nodes/" + entityId.to_s + "?output=JSON"
            $log.info @urlEntity
            RestClient::Resource.new(@urlEntity,@user+"@"+@account,@pass)
  end
  # TO DO Add code to choke if config parameters are not there
end
input() click to toggle source

Start appdynamics Trap listener Add the code to run this

# File lib/fluent/plugin/in_appdynamics.rb, line 228
def input
  if not @stop_flag
    alertEnd = Engine.now.to_i * 1000
    #alertStart = (Engine.now.to_f * 1000).to_i - @interval.to_i
    #alertStart = Engine.now.to_i * 1000
    if @state_store.last_records(@tag) 
      alertStart = @state_store.last_records(@tag)
      $log.info @tag + " :: Got time record from state_store - #{alertStart}" 
    else
      alertStart = alertEnd.to_i - @interval.to_i
      #$log.info "Spectrum :: Got time record from initial config - #{alertStart}"
    end
    
    $log.info "appdynamics :: Polling alerts for time period: #{alertStart.to_i} - #{alertEnd.to_i}"
    # Post to Appdynamics and parse results

    begin
            responsePost=appdynamicsEnd(alertStart,alertEnd).get
            #@state_store.update(pollingEnd, @tag)
            pollingDuration = alertEnd - alertStart
    rescue Exception => e
            $log.info e.message
            $log.info e.backtrace.inspect
    end
    # body is an array of hashes
    body = JSON.parse(responsePost.body)
    body.each_with_index {|val, index| 
            #pp val
            $log.debug val
            if @include_raw.to_s == "true"  
                    # Deep copy
                    rawObj=val.clone
                    #val << { "raw" => "#rawObj" }
                    val["raw"]=rawObj
            end
            # Need to do another call to get the hostname
            if ((val["affectedEntityDefinition"] || {})["entityId"] != nil) then
                    begin
                            responsePostAffEnt=appdynamicsEntEnd(val["affectedEntityDefinition"]["entityId"]).get
                            bodyAffEntity = JSON.parse(responsePostAffEnt.body)
                            val["AffectedEntityName"]=bodyAffEntity[0]["name"]
                            
                    rescue Exception => e
                            $log.info e.message
                            $log.info e.backtrace.inspect
                            val["TrigerredEntityName"]=""
                    end
                    #pp bodyAffEntity["name"]
                    #val["AffectedEntityName"]=bodyAffEntity["name"]

            end
            if ((val["triggeredEntityDefinition"] || {})["entityId"] != nil) then
                    begin
                            responsePostTrigEnt=appdynamicsEntEnd(val["triggeredEntityDefinition"]["entityId"]).get
                            bodyTrigEnt = JSON.parse(responsePostTrigEnt.body)
                            val["TrigerredEntityName"]=bodyTrigEnt[0]["name"]
                    rescue Exception => e
                            $log.info e.message
                            $log.info e.backtrace.inspect
                            val["TrigerredEntityName"]=""
                    end
                    #val["TrigerredEntityName"]=bodyTrigEnt["name"]
            end
            val["event_type"] = @tag.to_s
            val["receive_time_input"]=(Engine.now * 1000).to_s
            #puts "#{val} => #{index}"
            $log.info val
            begin
                    Engine.emit(@tag, val['startTimeInMillis'].to_i,val)
                    #@state_store.update
            rescue Exception => e
                    $log.info e.message
                    $log.info e.backtrace.inspect
            end
    }
    #pp body.class
    @state_store.update_records(alertEnd, @tag)
  end # END Stop flag
end
run() click to toggle source
# File lib/fluent/plugin/in_appdynamics.rb, line 218
def run
  @loop.run
  $log.info "Running appdynamics Input"
rescue
  $log.error "unexpected error", :error=>$!.to_s
  $log.error_backtrace
end
shutdown() click to toggle source

Stop Listener and cleanup any open connections.

Calls superclass method
# File lib/fluent/plugin/in_appdynamics.rb, line 211
def shutdown
  super
  @stop_flag = true
  @loop.stop
  @thread.join
end
start() click to toggle source
Calls superclass method
# File lib/fluent/plugin/in_appdynamics.rb, line 199
def start
  super
  @stop_flag = false
  @loop = Coolio::Loop.new
  #timer_trigger = TimerWatcher.new(@interval, true, &method(:input))
  #timer_trigger.attach(@loop)
  @loop.attach(TimerWatcher.new(@interval, true, &method(:input)))
  @thread = Thread.new(&method(:run))
  $log.info "starting appdynamics poller, interval #{@interval}"
end
to_utf8(str) click to toggle source

function to UTF8 encode

# File lib/fluent/plugin/in_appdynamics.rb, line 134
def to_utf8(str)
  str = str.force_encoding('UTF-8')
  return str if str.valid_encoding?
  str.encode("UTF-8", 'binary', invalid: :replace, undef: :replace, replace: '')
end