forked from Mirrors/freeswitch
added cpu monitor
This commit is contained in:
parent
428931bce2
commit
6ddcb9044c
@ -72,7 +72,8 @@ $(SRC)/libteletone_detect.c \
|
||||
$(SRC)/libteletone_generate.c \
|
||||
$(SRC)/ftdm_buffer.c \
|
||||
$(SRC)/ftdm_threadmutex.c \
|
||||
$(SRC)/ftdm_dso.c
|
||||
$(SRC)/ftdm_dso.c \
|
||||
$(SRC)/ftdm_cpu_monitor.c
|
||||
|
||||
library_include_HEADERS = \
|
||||
$(SRC)/include/fsk.h \
|
||||
@ -90,7 +91,8 @@ $(SRC)/include/ftdm_buffer.h \
|
||||
$(SRC)/include/ftdm_config.h \
|
||||
$(SRC)/include/ftdm_threadmutex.h \
|
||||
$(SRC)/include/ftdm_dso.h \
|
||||
$(SRC)/include/ftdm_types.h
|
||||
$(SRC)/include/ftdm_types.h \
|
||||
$(SRC)/include/ftdm_cpu_monitor.h
|
||||
|
||||
lib_LTLIBRARIES = libfreetdm.la
|
||||
libfreetdm_la_CFLAGS = $(AM_CFLAGS) $(MY_CFLAGS)
|
||||
|
@ -3142,6 +3142,8 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_freetdm_load)
|
||||
module_pool = pool;
|
||||
|
||||
ftdm_global_set_logger(ftdm_logger);
|
||||
|
||||
ftdm_cpu_monitor_disable();
|
||||
|
||||
if (ftdm_global_init() != FTDM_SUCCESS) {
|
||||
ftdm_log(FTDM_LOG_ERROR, "Error loading FreeTDM\n");
|
||||
|
271
libs/freetdm/src/ftdm_cpu_monitor.c
Normal file
271
libs/freetdm/src/ftdm_cpu_monitor.c
Normal file
@ -0,0 +1,271 @@
|
||||
/*
|
||||
* Copyright (c) 2010, Sangoma Technologies
|
||||
* Moises Silva <moy@sangoma.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* * Neither the name of the original author; nor the names of any contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* Contributors:
|
||||
* David Yat Sin <dyatsin@sangoma.com>
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef WIN32
|
||||
#define _WIN32_WINNT 0x0501 // To make GetSystemTimes visible in windows.h
|
||||
#include <windows.h>
|
||||
#else /* LINUX */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#endif
|
||||
|
||||
#include "freetdm.h"
|
||||
#include "ftdm_cpu_monitor.h"
|
||||
struct ftdm_cpu_monitor_stats
|
||||
{
|
||||
/* bool, just used to retrieve the values for the first time and not calculate the percentage of idle time */
|
||||
int valid_last_times;
|
||||
|
||||
/* last calculated percentage of idle time */
|
||||
double last_percentage_of_idle_time;
|
||||
|
||||
#ifdef __linux__
|
||||
/* all of these are the Linux jiffies last retrieved count */
|
||||
unsigned long long last_user_time;
|
||||
unsigned long long last_system_time;
|
||||
unsigned long long last_idle_time;
|
||||
|
||||
unsigned long long last_nice_time;
|
||||
unsigned long long last_irq_time;
|
||||
unsigned long long last_soft_irq_time;
|
||||
unsigned long long last_io_wait_time;
|
||||
unsigned long long last_steal_time;
|
||||
|
||||
/* /proc/stat file descriptor used to retrieve the counters */
|
||||
int procfd;
|
||||
int initd;
|
||||
#elif defined (WIN32) || defined (WIN64)
|
||||
__int64 i64LastUserTime;
|
||||
__int64 i64LastKernelTime;
|
||||
__int64 i64LastIdleTime;
|
||||
#else
|
||||
/* Unsupported */
|
||||
#endif
|
||||
};
|
||||
|
||||
#ifdef __linux__
|
||||
static ftdm_status_t ftdm_cpu_read_stats(struct ftdm_cpu_monitor_stats *p,
|
||||
unsigned long long *user,
|
||||
unsigned long long *nice,
|
||||
unsigned long long *system,
|
||||
unsigned long long *idle,
|
||||
unsigned long long *iowait,
|
||||
unsigned long long *irq,
|
||||
unsigned long long *softirq,
|
||||
unsigned long long *steal)
|
||||
{
|
||||
// the output of proc should not change that often from one kernel to other
|
||||
// see fs/proc/proc_misc.c or fs/proc/stat.c in the Linux kernel for more details
|
||||
// also man 5 proc is useful
|
||||
#define CPU_ELEMENTS 8 // change this if you change the format string
|
||||
#define CPU_INFO_FORMAT "cpu %Lu %Lu %Lu %Lu %Lu %Lu %Lu %Lu"
|
||||
static const char procfile[] = "/proc/stat";
|
||||
int rc = 0;
|
||||
int myerrno = 0;
|
||||
int elements = 0;
|
||||
const char *cpustr = NULL;
|
||||
char statbuff[1024];
|
||||
|
||||
if (!p->initd) {
|
||||
p->procfd = open(procfile, O_RDONLY, 0);
|
||||
if(p->procfd == -1) {
|
||||
ftdm_log(FTDM_LOG_ERROR, "Failed to open CPU statistics file %s: %s\n", procfile, strerror(myerrno));
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
p->initd = 1;
|
||||
} else {
|
||||
lseek(p->procfd, 0L, SEEK_SET);
|
||||
}
|
||||
|
||||
rc = read(p->procfd, statbuff, sizeof(statbuff) - 1);
|
||||
if (rc <= 0) {
|
||||
myerrno = errno;
|
||||
ftdm_log(FTDM_LOG_ERROR, "Failed to read CPU statistics file %s: %s\n", procfile, strerror(myerrno));
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
|
||||
cpustr = strstr(statbuff, "cpu ");
|
||||
if (!cpustr) {
|
||||
ftdm_log(FTDM_LOG_ERROR, "wrong format for Linux proc cpu statistics: missing cpu string\n");
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
|
||||
elements = sscanf(cpustr, CPU_INFO_FORMAT, user, nice, system, idle, iowait, irq, softirq, steal);
|
||||
if (elements != CPU_ELEMENTS) {
|
||||
ftdm_log(FTDM_LOG_ERROR, "wrong format for Linux proc cpu statistics: expected %d elements, but just found %d\n", CPU_ELEMENTS, elements);
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef __linux__
|
||||
FT_DECLARE(ftdm_status_t) ftdm_cpu_get_system_idle_time (struct ftdm_cpu_monitor_stats *p, double *idle_percentage)
|
||||
{
|
||||
unsigned long long user, nice, system, idle, iowait, irq, softirq, steal;
|
||||
unsigned long long usertime, kerneltime, idletime, totaltime, halftime;
|
||||
|
||||
if (ftdm_cpu_read_stats(p, &user, &nice, &system, &idle, &iowait, &irq, &softirq, &steal)) {
|
||||
ftdm_log(FTDM_LOG_ERROR, "Failed to retrieve Linux CPU statistics\n");
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
|
||||
if (!p->valid_last_times) {
|
||||
// we dont strictly need to save all of them but I feel code is more clear if we do
|
||||
p->valid_last_times = 1;
|
||||
p->last_user_time = user;
|
||||
p->last_nice_time = nice;
|
||||
p->last_system_time = system;
|
||||
p->last_irq_time = irq;
|
||||
p->last_soft_irq_time = softirq;
|
||||
p->last_io_wait_time = iowait;
|
||||
p->last_steal_time = steal;
|
||||
p->last_idle_time = idle;
|
||||
p->last_percentage_of_idle_time = 100.0;
|
||||
*idle_percentage = p->last_percentage_of_idle_time;
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
usertime = (user - p->last_user_time) + (nice - p->last_nice_time);
|
||||
kerneltime = (system - p->last_system_time) + (irq - p->last_irq_time) + (softirq - p->last_soft_irq_time);
|
||||
kerneltime += (iowait - p->last_io_wait_time);
|
||||
kerneltime += (steal - p->last_steal_time);
|
||||
idletime = (idle - p->last_idle_time);
|
||||
|
||||
totaltime = usertime + kerneltime + idletime;
|
||||
|
||||
if (totaltime <= 0) {
|
||||
// this may happen if not enough time has elapsed and the jiffies counters are the same than the last time we checked
|
||||
// jiffies depend on timer interrupts which depend on the number of HZ compile time setting of the kernel
|
||||
// typical configs set HZ to 100 (that means, 100 jiffies updates per second, that is one each 10ms)
|
||||
// avoid an arithmetic exception and return the same values
|
||||
*idle_percentage = p->last_percentage_of_idle_time;
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
halftime = totaltime / 2UL;
|
||||
|
||||
p->last_percentage_of_idle_time = ((100 * idletime + halftime) / totaltime);
|
||||
*idle_percentage = p->last_percentage_of_idle_time;
|
||||
|
||||
p->last_user_time = user;
|
||||
p->last_nice_time = nice;
|
||||
p->last_system_time = system;
|
||||
p->last_irq_time = irq;
|
||||
p->last_soft_irq_time = softirq;
|
||||
p->last_io_wait_time = iowait;
|
||||
p->last_steal_time = steal;
|
||||
p->last_idle_time = idle;
|
||||
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
#elif defined (WIN32) || defined (WIN64)
|
||||
FT_DECLARE(ftdm_status_t) ftdm_cpu_get_system_idle_time(struct ftdm_cpu_monitor_stats *p, double *idle_percentage)
|
||||
{
|
||||
FILETIME idleTime;
|
||||
FILETIME kernelTime;
|
||||
FILETIME userTime;
|
||||
|
||||
if (!::GetSystemTimes(&idleTime, &kernelTime, &userTime)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
__int64 i64UserTime = (__int64)userTime.dwLowDateTime | ((__int64)userTime.dwHighDateTime << 32);
|
||||
|
||||
__int64 i64KernelTime = (__int64)kernelTime.dwLowDateTime | ((__int64)kernelTime.dwHighDateTime << 32);
|
||||
|
||||
__int64 i64IdleTime = (__int64)idleTime.dwLowDateTime | ((__int64)idleTime.dwHighDateTime << 32);
|
||||
|
||||
if (p->valid_last_times) {
|
||||
__int64 i64User = i64UserTime - p->i64LastUserTime;
|
||||
__int64 i64Kernel = i64KernelTime - p->i64LastKernelTime;
|
||||
__int64 i64Idle = i64IdleTime - p->i64LastIdleTime;
|
||||
__int64 i64System = i64User + i64Kernel;
|
||||
*idle_percentage = 100.0 * i64Idle / i64System;
|
||||
} else {
|
||||
*idle_percentage = 100.0;
|
||||
p->valid_last_times = 1;
|
||||
}
|
||||
|
||||
/* Remember current value for the next call */
|
||||
p->i64LastUserTime = i64UserTime;
|
||||
p->i64LastKernelTime = i64KernelTime;
|
||||
p->i64LastIdleTime = i64IdleTime;
|
||||
|
||||
/* Success */
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
#else
|
||||
/* Unsupported */
|
||||
FT_DECLARE(ftdm_status_t) ftdm_cpu_get_system_idle_time(struct ftdm_cpu_monitor_stats *p, double *idle_percentage)
|
||||
{
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
#endif
|
||||
|
||||
FT_DECLARE(struct ftdm_cpu_monitor_stats*) ftdm_new_cpu_monitor(void)
|
||||
{
|
||||
return calloc(1, sizeof(struct ftdm_cpu_monitor_stats));
|
||||
}
|
||||
|
||||
FT_DECLARE(void) ftdm_delete_cpu_monitor(struct ftdm_cpu_monitor_stats *p)
|
||||
{
|
||||
#ifdef __linux__
|
||||
close(p->procfd);
|
||||
#endif
|
||||
free(p);
|
||||
}
|
||||
|
||||
|
||||
/* For Emacs:
|
||||
* Local Variables:
|
||||
* mode:c
|
||||
* indent-tabs-mode:t
|
||||
* tab-width:4
|
||||
* c-basic-offset:4
|
||||
* End:
|
||||
* For VIM:
|
||||
* vim:set softtabstop=4 shiftwidth=4 tabstop=4:
|
||||
*/
|
@ -48,6 +48,7 @@
|
||||
#ifdef FTDM_PIKA_SUPPORT
|
||||
#include "ftdm_pika.h"
|
||||
#endif
|
||||
#include "ftdm_cpu_monitor.h"
|
||||
|
||||
#define SPAN_PENDING_CHANS_QUEUE_SIZE 1000
|
||||
|
||||
@ -80,6 +81,16 @@ FT_DECLARE(ftdm_time_t) ftdm_current_time_in_ms(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
uint8_t running;
|
||||
uint8_t alarm;
|
||||
uint32_t interval;
|
||||
uint8_t alarm_action_flags;
|
||||
uint8_t set_alarm_threshold;
|
||||
uint8_t reset_alarm_threshold;
|
||||
ftdm_interrupt_t *interrupt;
|
||||
} cpu_monitor_t;
|
||||
|
||||
static struct {
|
||||
ftdm_hash_t *interface_hash;
|
||||
ftdm_hash_t *module_hash;
|
||||
@ -93,8 +104,16 @@ static struct {
|
||||
uint32_t running;
|
||||
ftdm_span_t *spans;
|
||||
ftdm_group_t *groups;
|
||||
cpu_monitor_t cpu_monitor;
|
||||
} globals;
|
||||
|
||||
static uint8_t ftdm_cpu_monitor_disabled = 0;
|
||||
|
||||
enum ftdm_enum_cpu_alarm_action_flags
|
||||
{
|
||||
FTDM_CPU_ALARM_ACTION_WARN = (1 << 0),
|
||||
FTDM_CPU_ALARM_ACTION_REJECT = (1 << 1)
|
||||
};
|
||||
|
||||
/* enum lookup funcs */
|
||||
FTDM_ENUM_NAMES(TONEMAP_NAMES, TONEMAP_STRINGS)
|
||||
@ -1470,6 +1489,14 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_open_chan(ftdm_channel_t *ftdmchan)
|
||||
snprintf(ftdmchan->last_error, sizeof(ftdmchan->last_error), "%s", "Channel is alarmed\n");
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
|
||||
if (globals.cpu_monitor.alarm &&
|
||||
globals.cpu_monitor.alarm_action_flags & FTDM_CPU_ALARM_ACTION_REJECT) {
|
||||
snprintf(ftdmchan->last_error, sizeof(ftdmchan->last_error), "%s", "CPU usage alarm is on - refusing to open channel\n");
|
||||
ftdm_log(FTDM_LOG_WARNING, "CPU usage alarm is on - refusing to open channel\n");
|
||||
ftdmchan->caller_data.hangup_cause = FTDM_CAUSE_SWITCH_CONGESTION;
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
|
||||
if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_READY) || (status = ftdm_mutex_trylock(ftdmchan->mutex)) != FTDM_SUCCESS) {
|
||||
snprintf(ftdmchan->last_error, sizeof(ftdmchan->last_error), "Channel is not ready or is in use %d %d", ftdm_test_flag(ftdmchan, FTDM_CHANNEL_READY), status);
|
||||
@ -2988,6 +3015,44 @@ static ftdm_status_t load_config(void)
|
||||
} else {
|
||||
ftdm_log(FTDM_LOG_ERROR, "unknown span variable '%s'\n", var);
|
||||
}
|
||||
} else if (!strncasecmp(cfg.category, "general", 7)) {
|
||||
if (!strncasecmp(var, "cpu_monitoring_interval", sizeof("cpu_monitoring_interval")-1)) {
|
||||
if (atoi(val) > 0) {
|
||||
globals.cpu_monitor.interval = atoi(val);
|
||||
} else {
|
||||
ftdm_log(FTDM_LOG_ERROR, "Invalid cpu monitoring interval %s\n", val);
|
||||
}
|
||||
} else if (!strncasecmp(var, "cpu_set_alarm_threshold", sizeof("cpu_set_alarm_threshold")-1)) {
|
||||
if (atoi(val) > 0 && atoi(val) < 100) {
|
||||
globals.cpu_monitor.set_alarm_threshold = atoi(val);
|
||||
} else {
|
||||
ftdm_log(FTDM_LOG_ERROR, "Invalid cpu alarm set threshold %s\n", val);
|
||||
}
|
||||
} else if (!strncasecmp(var, "cpu_reset_alarm_threshold", sizeof("cpu_reset_alarm_threshold")-1)) {
|
||||
if (atoi(val) > 0 && atoi(val) < 100) {
|
||||
globals.cpu_monitor.reset_alarm_threshold = atoi(val);
|
||||
if (globals.cpu_monitor.reset_alarm_threshold > globals.cpu_monitor.set_alarm_threshold) {
|
||||
globals.cpu_monitor.reset_alarm_threshold = globals.cpu_monitor.set_alarm_threshold - 10;
|
||||
ftdm_log(FTDM_LOG_ERROR, "Cpu alarm reset threshold must be lower than set threshold"
|
||||
", setting threshold to %d\n", globals.cpu_monitor.reset_alarm_threshold);
|
||||
}
|
||||
} else {
|
||||
ftdm_log(FTDM_LOG_ERROR, "Invalid cpu alarm reset threshold %s\n", val);
|
||||
}
|
||||
} else if (!strncasecmp(var, "cpu_alarm_action", sizeof("cpu_alarm_action")-1)) {
|
||||
char* p = val;
|
||||
do {
|
||||
if (!strncasecmp(p, "reject", sizeof("reject")-1)) {
|
||||
globals.cpu_monitor.alarm_action_flags |= FTDM_CPU_ALARM_ACTION_REJECT;
|
||||
} else if (!strncasecmp(p, "warn", sizeof("warn")-1)) {
|
||||
globals.cpu_monitor.alarm_action_flags |= FTDM_CPU_ALARM_ACTION_WARN;
|
||||
}
|
||||
p = strchr(p, ',');
|
||||
if (p) {
|
||||
while(*p++) if (*p != 0x20) break;
|
||||
}
|
||||
} while (p);
|
||||
}
|
||||
} else {
|
||||
ftdm_log(FTDM_LOG_ERROR, "unknown param [%s] '%s' / '%s'\n", cfg.category, var, val);
|
||||
}
|
||||
@ -3516,6 +3581,71 @@ FT_DECLARE(ftdm_status_t) ftdm_span_send_signal(ftdm_span_t *span, ftdm_sigmsg_t
|
||||
return status;
|
||||
}
|
||||
|
||||
static void *ftdm_cpu_monitor_run(ftdm_thread_t *me, void *obj)
|
||||
{
|
||||
cpu_monitor_t *monitor = (cpu_monitor_t *)obj;
|
||||
struct ftdm_cpu_monitor_stats *cpu_stats = ftdm_new_cpu_monitor();
|
||||
if (!cpu_stats) {
|
||||
return NULL;
|
||||
}
|
||||
monitor->running = 1;
|
||||
|
||||
while(ftdm_running()) {
|
||||
double time;
|
||||
if (ftdm_cpu_get_system_idle_time(cpu_stats, &time)) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (monitor->alarm) {
|
||||
if ((int)time >= (100 - monitor->set_alarm_threshold)) {
|
||||
ftdm_log(FTDM_LOG_DEBUG, "CPU alarm OFF (idle:%d)\n", (int) time);
|
||||
monitor->alarm = 0;
|
||||
}
|
||||
if (monitor->alarm_action_flags & FTDM_CPU_ALARM_ACTION_WARN) {
|
||||
ftdm_log(FTDM_LOG_WARNING, "CPU alarm is ON (cpu usage:%d)\n", (int) (100-time));
|
||||
}
|
||||
} else {
|
||||
if ((int)time <= (100-monitor->reset_alarm_threshold)) {
|
||||
ftdm_log(FTDM_LOG_DEBUG, "CPU alarm ON (idle:%d)\n", (int) time);
|
||||
monitor->alarm = 1;
|
||||
}
|
||||
}
|
||||
ftdm_interrupt_wait(monitor->interrupt, monitor->interval);
|
||||
}
|
||||
|
||||
ftdm_delete_cpu_monitor(cpu_stats);
|
||||
monitor->running = 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static ftdm_status_t ftdm_cpu_monitor_start(cpu_monitor_t* monitor)
|
||||
{
|
||||
if (ftdm_interrupt_create(&monitor->interrupt, FTDM_INVALID_SOCKET) != FTDM_SUCCESS) {
|
||||
ftdm_log(FTDM_LOG_CRIT, "Failed to create CPU monitor interrupt\n");
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
|
||||
if (ftdm_thread_create_detached(ftdm_cpu_monitor_run, monitor) != FTDM_SUCCESS) {
|
||||
ftdm_log(FTDM_LOG_CRIT, "Failed to create cpu monitor thread!!\n");
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
static void ftdm_cpu_monitor_stop(cpu_monitor_t* monitor)
|
||||
{
|
||||
ftdm_interrupt_signal(monitor->interrupt);
|
||||
while(monitor->running) {
|
||||
ftdm_sleep(10);
|
||||
}
|
||||
}
|
||||
|
||||
FT_DECLARE(void) ftdm_cpu_monitor_disable(void)
|
||||
{
|
||||
ftdm_cpu_monitor_disabled = 1;
|
||||
}
|
||||
|
||||
|
||||
FT_DECLARE(ftdm_status_t) ftdm_global_init(void)
|
||||
{
|
||||
memset(&globals, 0, sizeof(globals));
|
||||
@ -3538,14 +3668,34 @@ FT_DECLARE(ftdm_status_t) ftdm_global_init(void)
|
||||
|
||||
FT_DECLARE(ftdm_status_t) ftdm_global_configuration(void)
|
||||
{
|
||||
int modcount = ftdm_load_modules();
|
||||
int modcount = 0;
|
||||
|
||||
if (!globals.running) {
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
|
||||
modcount = ftdm_load_modules();
|
||||
|
||||
ftdm_log(FTDM_LOG_NOTICE, "Modules configured: %d \n", modcount);
|
||||
|
||||
globals.cpu_monitor.interval = 1000;
|
||||
globals.cpu_monitor.alarm_action_flags = FTDM_CPU_ALARM_ACTION_WARN | FTDM_CPU_ALARM_ACTION_REJECT;
|
||||
globals.cpu_monitor.set_alarm_threshold = 80;
|
||||
globals.cpu_monitor.reset_alarm_threshold = 70;
|
||||
|
||||
if (load_config() != FTDM_SUCCESS) {
|
||||
globals.running = 0;
|
||||
ftdm_log(FTDM_LOG_ERROR, "FreeTDM global configuration failed!\n");
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
|
||||
if (!ftdm_cpu_monitor_disabled) {
|
||||
if (ftdm_cpu_monitor_start(&globals.cpu_monitor) != FTDM_SUCCESS) {
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
@ -3563,6 +3713,8 @@ FT_DECLARE(ftdm_status_t) ftdm_global_destroy(void)
|
||||
|
||||
globals.running = 0;
|
||||
|
||||
ftdm_cpu_monitor_stop(&globals.cpu_monitor);
|
||||
|
||||
globals.span_index = 0;
|
||||
|
||||
ftdm_span_close_all();
|
||||
@ -3596,6 +3748,7 @@ FT_DECLARE(ftdm_status_t) ftdm_global_destroy(void)
|
||||
ftdm_mutex_unlock(globals.mutex);
|
||||
ftdm_mutex_destroy(&globals.mutex);
|
||||
ftdm_mutex_destroy(&globals.span_mutex);
|
||||
ftdm_interrupt_destroy(&globals.cpu_monitor.interrupt);
|
||||
|
||||
memset(&globals, 0, sizeof(globals));
|
||||
return FTDM_SUCCESS;
|
||||
|
@ -880,8 +880,8 @@ static __inline__ void advance_chan_states(ftdm_channel_t *ftdmchan);
|
||||
*/
|
||||
static void handle_call_start(ftdm_span_t *span, sangomabc_connection_t *mcon, sangomabc_event_t *event)
|
||||
{
|
||||
ftdm_channel_t *ftdmchan;
|
||||
|
||||
ftdm_channel_t *ftdmchan = NULL;
|
||||
int hangup_cause = FTDM_CAUSE_CALL_REJECTED;
|
||||
if (!(ftdmchan = find_ftdmchan(span, (sangomabc_short_event_t*)event, 0))) {
|
||||
if ((ftdmchan = find_ftdmchan(span, (sangomabc_short_event_t*)event, 1))) {
|
||||
int r;
|
||||
@ -896,7 +896,7 @@ static void handle_call_start(ftdm_span_t *span, sangomabc_connection_t *mcon, s
|
||||
|
||||
}
|
||||
ftdm_set_sflag(ftdmchan, SFLAG_SENT_FINAL_MSG);
|
||||
ftdmchan=NULL;
|
||||
ftdmchan = NULL;
|
||||
}
|
||||
ftdm_log(FTDM_LOG_CRIT, "START CANT FIND CHAN %d:%d\n", event->span+1,event->chan+1);
|
||||
goto error;
|
||||
@ -953,12 +953,13 @@ static void handle_call_start(ftdm_span_t *span, sangomabc_connection_t *mcon, s
|
||||
return;
|
||||
|
||||
error:
|
||||
hangup_cause = ftdmchan ? ftdmchan->caller_data.hangup_cause : FTDM_CAUSE_REQUESTED_CHAN_UNAVAIL;
|
||||
sangomabc_exec_command(mcon,
|
||||
event->span,
|
||||
event->chan,
|
||||
0,
|
||||
SIGBOOST_EVENT_CALL_START_NACK,
|
||||
0, 0);
|
||||
hangup_cause, 0);
|
||||
|
||||
}
|
||||
|
||||
|
@ -824,6 +824,7 @@ FT_DECLARE(ftdm_status_t) ftdm_span_find_by_name(const char *name, ftdm_span_t *
|
||||
FT_DECLARE(char *) ftdm_api_execute(const char *type, const char *cmd);
|
||||
FT_DECLARE(int) ftdm_vasprintf(char **ret, const char *fmt, va_list ap);
|
||||
FT_DECLARE(ftdm_status_t) ftdm_channel_set_caller_data(ftdm_channel_t *ftdmchan, ftdm_caller_data_t *caller_data);
|
||||
FT_DECLARE(void) ftdm_cpu_monitor_disable(void);
|
||||
|
||||
FIO_CODEC_FUNCTION(fio_slin2ulaw);
|
||||
FIO_CODEC_FUNCTION(fio_ulaw2slin);
|
||||
|
75
libs/freetdm/src/include/ftdm_cpu_monitor.h
Normal file
75
libs/freetdm/src/include/ftdm_cpu_monitor.h
Normal file
@ -0,0 +1,75 @@
|
||||
/*
|
||||
* Copyright (c) 2010, Sangoma Technologies
|
||||
* Moises Silva <moy@sangoma.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* * Neither the name of the original author; nor the names of any contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*
|
||||
* Contributors:
|
||||
* David Yat Sin <dyatsin@sangoma.com>
|
||||
*
|
||||
*/
|
||||
|
||||
/*! \brief opaque cpu stats structure */
|
||||
struct ftdm_cpu_monitor_stats;
|
||||
|
||||
/*!
|
||||
* \brief create a new cpu monitor
|
||||
* \return profile timer structure previously created with new_profile_timer, NULL on error
|
||||
*/
|
||||
FT_DECLARE(struct ftdm_cpu_monitor_stats*) ftdm_new_cpu_monitor(void);
|
||||
|
||||
/*!
|
||||
* \brief Deletes cpu_monitor
|
||||
*/
|
||||
FT_DECLARE(void) ftdm_delete_cpu_monitor(struct ftdm_cpu_monitor_stats *p);
|
||||
|
||||
/*!
|
||||
* \brief provides the percentage of idle system time
|
||||
* \param p cpu_stats structure previously created with ftdm_new_cpu_monitor
|
||||
* \param pointer to store the percentage of idle time
|
||||
* \return -1 on error 0 for success
|
||||
*/
|
||||
FT_DECLARE(ftdm_status_t) ftdm_cpu_get_system_idle_time (struct ftdm_cpu_monitor_stats *p, double *idle_percentage);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* For Emacs:
|
||||
* Local Variables:
|
||||
* mode:c
|
||||
* indent-tabs-mode:t
|
||||
* tab-width:4
|
||||
* c-basic-offset:4
|
||||
* End:
|
||||
* For VIM:
|
||||
* vim:set softtabstop=4 shiftwidth=4 tabstop=4:
|
||||
*/
|
Loading…
Reference in New Issue
Block a user