Skip to content
Snippets Groups Projects
Commit 46d67b77 authored by Nigel Kukard's avatar Nigel Kukard
Browse files

Reworked tcstats plugin against new API

parent 138f29cd
No related branches found
No related tags found
No related merge requests found
# OpenTrafficShaper Linux tcstats traffic shaping statistics # OpenTrafficShaper Linux tcstats traffic shaping statistics
# Copyright (C) 2007-2013, AllWorldIT # Copyright (C) 2007-2014, AllWorldIT
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by # it under the terms of the GNU General Public License as published by
...@@ -31,7 +31,7 @@ use opentrafficshaper::logger; ...@@ -31,7 +31,7 @@ use opentrafficshaper::logger;
use opentrafficshaper::utils; use opentrafficshaper::utils;
use opentrafficshaper::plugins::configmanager qw( use opentrafficshaper::plugins::configmanager qw(
getInterfaces getInterfaces
); );
...@@ -45,7 +45,7 @@ our (@ISA,@EXPORT,@EXPORT_OK); ...@@ -45,7 +45,7 @@ our (@ISA,@EXPORT,@EXPORT_OK);
); );
use constant { use constant {
VERSION => '0.0.1', VERSION => '0.1.2',
# How often our config check ticks # How often our config check ticks
TICK_PERIOD => 5, TICK_PERIOD => 5,
...@@ -82,23 +82,23 @@ sub plugin_init ...@@ -82,23 +82,23 @@ sub plugin_init
# Setup our environment # Setup our environment
$logger = $globals->{'logger'}; $logger = $globals->{'logger'};
$logger->log(LOG_NOTICE,"[TCSTATS] OpenTrafficShaper tc Statistics Integration v".VERSION." - Copyright (c) 2013, AllWorldIT"); $logger->log(LOG_NOTICE,"[TCSTATS] OpenTrafficShaper tc Statistics Integration v%s - Copyright (c) 2013-2014, AllWorldIT",
VERSION
);
# This session is our main session, its alias is "shaper" # This session is our main session, its alias is "shaper"
POE::Session->create( POE::Session->create(
inline_states => { inline_states => {
_start => \&session_start, _start => \&_session_start,
_stop => \&session_stop, _stop => \&_session_stop,
_tick => \&_session_tick,
tick => \&session_tick,
# Internal _task_child_stdout => \&_task_child_stdout,
task_child_stdout => \&task_child_stdout, _task_child_stderr => \&_task_child_stderr,
task_child_stderr => \&task_child_stderr, _task_child_close => \&_task_child_close,
task_child_close => \&task_child_close,
# Signals _SIGCHLD => \&_task_handle_SIGCHLD,
handle_SIGCHLD => \&task_handle_SIGCHLD, _SIGINT => \&_task_handle_SIGINT,
handle_SIGINT => \&task_handle_SIGINT,
} }
); );
...@@ -114,7 +114,7 @@ sub plugin_start ...@@ -114,7 +114,7 @@ sub plugin_start
# Initialize this plugins main POE session # Initialize this plugins main POE session
sub session_start sub _session_start
{ {
my ($kernel,$heap) = @_[KERNEL,HEAP]; my ($kernel,$heap) = @_[KERNEL,HEAP];
...@@ -123,14 +123,14 @@ sub session_start ...@@ -123,14 +123,14 @@ sub session_start
$kernel->alias_set("tcstats"); $kernel->alias_set("tcstats");
# Set delay on config updates # Set delay on config updates
$kernel->delay(tick => TICK_PERIOD); $kernel->delay('_tick' => TICK_PERIOD);
$logger->log(LOG_DEBUG,"[TCSTATS] Initialized"); $logger->log(LOG_DEBUG,"[TCSTATS] Initialized");
} }
# Shut down session # Shut down session
sub session_stop sub _session_stop
{ {
my ($kernel,$heap) = @_[KERNEL,HEAP]; my ($kernel,$heap) = @_[KERNEL,HEAP];
...@@ -146,7 +146,7 @@ sub session_stop ...@@ -146,7 +146,7 @@ sub session_stop
# Time ticker for processing changes # Time ticker for processing changes
sub session_tick sub _session_tick
{ {
my ($kernel,$heap) = @_[KERNEL,HEAP]; my ($kernel,$heap) = @_[KERNEL,HEAP];
...@@ -159,11 +159,13 @@ sub session_tick ...@@ -159,11 +159,13 @@ sub session_tick
foreach my $interface (@{getInterfaces()}) { foreach my $interface (@{getInterfaces()}) {
# Skip to next if we've already run for this interface # Skip to next if we've already run for this interface
if (defined($lastStats->{$interface}) && $lastStats->{$interface} + opentrafficshaper::plugins::statistics::STATISTICS_PERIOD > $now) { if (defined($lastStats->{$interface}) &&
$lastStats->{$interface} + opentrafficshaper::plugins::statistics::STATISTICS_PERIOD > $now
) {
next; next;
} }
$logger->log(LOG_INFO,"[TCSTATS] Generating stats for '$interface'"); $logger->log(LOG_INFO,"[TCSTATS] Generating stats for '%s'",$interface);
# TC commands to run # TC commands to run
my $cmd = [ '/sbin/tc', '-s', 'class', 'show', 'dev', $interface, 'parent', '1:' ]; my $cmd = [ '/sbin/tc', '-s', 'class', 'show', 'dev', $interface, 'parent', '1:' ];
...@@ -174,13 +176,13 @@ sub session_tick ...@@ -174,13 +176,13 @@ sub session_tick
StdinFilter => POE::Filter::Line->new(), StdinFilter => POE::Filter::Line->new(),
StdoutFilter => POE::Filter::TCStatistics->new(), StdoutFilter => POE::Filter::TCStatistics->new(),
StderrFilter => POE::Filter::Line->new(), StderrFilter => POE::Filter::Line->new(),
StdoutEvent => 'task_child_stdout', StdoutEvent => '_task_child_stdout',
StderrEvent => 'task_child_stderr', StderrEvent => '_task_child_stderr',
CloseEvent => 'task_child_close', CloseEvent => '_task_child_close',
) or $logger->log(LOG_ERR,"[TCSTATS] TC: Unable to start task"); ) or $logger->log(LOG_ERR,"[TCSTATS] TC: Unable to start task");
# Intercept SIGCHLD # Intercept SIGCHLD
$kernel->sig_child($task->ID, "handle_SIGCHLD"); $kernel->sig_child($task->ID, "_SIGCHLD");
# Wheel events include the wheel's ID. # Wheel events include the wheel's ID.
$heap->{task_by_wid}->{$task->ID} = $task; $heap->{task_by_wid}->{$task->ID} = $task;
...@@ -195,7 +197,7 @@ sub session_tick ...@@ -195,7 +197,7 @@ sub session_tick
# Build commandline string # Build commandline string
my $cmdStr = join(' ',@{$cmd}); my $cmdStr = join(' ',@{$cmd});
$logger->log(LOG_DEBUG,"[TCSTATS] TASK/".$task->ID.": Starting '$cmdStr' as ".$task->ID." with PID ".$task->PID); $logger->log(LOG_DEBUG,"[TCSTATS] TASK/%s: Starting '%s' as %s with PID %s",$task->ID,$cmdStr,$task->ID,$task->PID);
# Set last time we were run to now # Set last time we were run to now
$lastStats->{$interface} = $now; $lastStats->{$interface} = $now;
...@@ -207,15 +209,17 @@ sub session_tick ...@@ -207,15 +209,17 @@ sub session_tick
# If we didn't fire up any stats, re-tick # If we didn't fire up any stats, re-tick
if (!$interfaceCount) { if (!$interfaceCount) {
$kernel->delay(tick => TICK_PERIOD); $kernel->delay('_tick' => TICK_PERIOD);
} }
}; };
# Child writes to STDOUT # Child writes to STDOUT
sub task_child_stdout sub _task_child_stdout
{ {
my ($kernel,$heap,$stat,$task_id) = @_[KERNEL,HEAP,ARG0,ARG1]; my ($kernel,$heap,$stat,$task_id) = @_[KERNEL,HEAP,ARG0,ARG1];
my $task = $heap->{task_by_wid}->{$task_id}; my $task = $heap->{task_by_wid}->{$task_id};
# Grab task data # Grab task data
...@@ -230,29 +234,38 @@ sub task_child_stdout ...@@ -230,29 +234,38 @@ sub task_child_stdout
my $direction = opentrafficshaper::plugins::statistics::STATISTICS_DIR_TX; my $direction = opentrafficshaper::plugins::statistics::STATISTICS_DIR_TX;
# Is this a system class? # Is this a system class?
# XXX: _class_parent is hard coded to 1
my $classChildDec = hex($stat->{'_class_child'}); my $classChildDec = hex($stat->{'_class_child'});
if ($stat->{'_class_parent'} == 1) { # Check if this is a limit class...
# Check if this is a limit class... if (opentrafficshaper::plugins::tc::isPoolTcClass($interface,$stat->{'_class_parent'},$stat->{'_class_child'})) {
if (opentrafficshaper::plugins::tc::isTcLimitClass($interface,1,$stat->{'_class_child'})) {
if (defined(my $lid = opentrafficshaper::plugins::tc::getLIDFromTcLimitClass($interface,$stat->{'_class_child'}))) { if (defined(my $pid = opentrafficshaper::plugins::tc::getPIDFromTcClass($interface,$stat->{'_class_parent'},
$sid = opentrafficshaper::plugins::statistics::setSIDFromLID($lid); $stat->{'_class_child'}))
$direction = opentrafficshaper::plugins::statistics::getTrafficDirection($lid,$interface); ) {
} else { $sid = opentrafficshaper::plugins::statistics::setSIDFromPID($pid);
$logger->log(LOG_WARN,"[TCSTATS] Limit traffic class '%s:%s' NOT FOUND",$stat->{'_class_parent'},$stat->{'_class_child'}); $direction = opentrafficshaper::plugins::statistics::getTrafficDirection($pid,$interface);
}
} else { } else {
# Class = 1 is the root $logger->log(LOG_WARN,"[TCSTATS] Pool traffic class '%s:%s' NOT FOUND",$stat->{'_class_parent'},
if ($classChildDec == 1) { $stat->{'_class_child'}
# This is a special case case );
$sid = opentrafficshaper::plugins::statistics::setSIDFromCID($interface,0); }
} else {
# Class = 1 is the root
# XXX: Should this be hard coded or used like TC_ROOT_CLASS is
if ($classChildDec == 1) {
# This is a special case case
$sid = opentrafficshaper::plugins::statistics::setSIDFromCID($interface,0);
} else {
# Save the class with the decimal number
if (my $classID = opentrafficshaper::plugins::tc::getCIDFromTcClass($interface,
opentrafficshaper::plugins::tc::TC_ROOT_CLASS,$stat->{'_class_child'})
) {
$sid = opentrafficshaper::plugins::statistics::setSIDFromCID($interface,$classID);
} else { } else {
# Save the class with the decimal number $logger->log(LOG_WARN,"[TCSTATS] System traffic class '%s:%s' NOT FOUND",$stat->{'_class_parent'},
if (my $classID = opentrafficshaper::plugins::tc::getCIDFromTcLimitClass($interface,1,$stat->{'_class_child'})) { $stat->{'_class_child'}
$sid = opentrafficshaper::plugins::statistics::setSIDFromCID($interface,$classID); );
} else {
$logger->log(LOG_WARN,"[TCSTATS] System traffic class '%s:%s' NOT FOUND",$stat->{'_class_parent'},$stat->{'_class_child'});
}
} }
} }
} }
...@@ -269,33 +282,36 @@ sub task_child_stdout ...@@ -269,33 +282,36 @@ sub task_child_stdout
# Child writes to STDERR # Child writes to STDERR
sub task_child_stderr sub _task_child_stderr
{ {
my ($kernel,$heap,$stdout,$task_id) = @_[KERNEL,HEAP,ARG0,ARG1]; my ($kernel,$heap,$stdout,$task_id) = @_[KERNEL,HEAP,ARG0,ARG1];
my $task = $heap->{task_by_wid}->{$task_id}; my $task = $heap->{task_by_wid}->{$task_id};
$logger->log(LOG_WARN,"[TCSTATS] TASK/$task_id: STDERR => ".$stdout); $logger->log(LOG_WARN,"[TCSTATS] TASK/%s: STDERR => %s",$task_id,$stdout);
} }
# Child closed its handles, it won't communicate with us, so remove it # Child closed its handles, it won't communicate with us, so remove it
sub task_child_close sub _task_child_close
{ {
my ($kernel,$heap,$task_id) = @_[KERNEL,HEAP,ARG0]; my ($kernel,$heap,$task_id) = @_[KERNEL,HEAP,ARG0];
my $task = $heap->{task_by_wid}->{$task_id}; my $task = $heap->{task_by_wid}->{$task_id};
my $taskData = $heap->{'task_data'}->{$task_id}; my $taskData = $heap->{'task_data'}->{$task_id};
# May have been reaped by task_sigchld() # May have been reaped by task_sigchld()
if (!defined($task)) { if (!defined($task)) {
$logger->log(LOG_DEBUG,"[TCSTATS] TASK/$task_id: Closed dead child"); $logger->log(LOG_DEBUG,"[TCSTATS] TASK/%s: Closed dead child",$task_id);
return; return;
} }
# Push consolidated update through # Push consolidated update through
$kernel->post("statistics" => "update" => $taskData->{'stats'}); $kernel->post("statistics" => "update" => $taskData->{'stats'});
$logger->log(LOG_DEBUG,"[TCSTATS] TASK/$task_id: Closed PID ".$task->PID); $logger->log(LOG_DEBUG,"[TCSTATS] TASK/%s: Closed PID %s",$task_id,$task->PID);
# Cleanup # Cleanup
delete($heap->{task_by_pid}->{$task->PID}); delete($heap->{task_by_pid}->{$task->PID});
...@@ -303,18 +319,18 @@ sub task_child_close ...@@ -303,18 +319,18 @@ sub task_child_close
delete($heap->{task_data}->{$task_id}); delete($heap->{task_data}->{$task_id});
# Fire up next tick # Fire up next tick
$kernel->delay(tick => TICK_PERIOD); $kernel->delay('_tick' => TICK_PERIOD);
} }
# Reap the dead child # Reap the dead child
sub task_handle_SIGCHLD sub _task_handle_SIGCHLD
{ {
my ($kernel,$heap,$pid,$status) = @_[KERNEL,HEAP,ARG1,ARG2]; my ($kernel,$heap,$pid,$status) = @_[KERNEL,HEAP,ARG1,ARG2];
my $task = $heap->{task_by_pid}->{$pid}; my $task = $heap->{task_by_pid}->{$pid};
$logger->log(LOG_DEBUG,"[TCSTATS] TASK: Task with PID $pid exited with status $status"); $logger->log(LOG_DEBUG,"[TCSTATS] TASK: Task with PID %s exited with status %s",$pid,$status);
# May have been reaped by task_child_close() # May have been reaped by task_child_close()
return if (!defined($task)); return if (!defined($task));
...@@ -327,7 +343,7 @@ sub task_handle_SIGCHLD ...@@ -327,7 +343,7 @@ sub task_handle_SIGCHLD
# Handle SIGINT # Handle SIGINT
sub task_handle_SIGINT sub _task_handle_SIGINT
{ {
my ($kernel,$heap,$signal_name) = @_[KERNEL,HEAP,ARG0]; my ($kernel,$heap,$signal_name) = @_[KERNEL,HEAP,ARG0];
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment