/** * Log when extra-debug is activated */ static function logIfExtradebug($file, $message) { if (!PluginFusioninventoryConfig::isExtradebugActive()) { return; } Toolbox::logInFile($file, $message); }
/** * Get logs of job * * @param array $task_ids list of tasks id * @return array */ function getJoblogs($task_ids = array()) { global $DB; $debug_mode = $_SESSION['glpi_use_mode'] == Session::DEBUG_MODE; $runclass = new PluginFusioninventoryTaskjobstate(); $run_states = $runclass->getStateNames(); $query_where = array(); $query_where[] = "WHERE 1"; if (isset($_SESSION['glpiactiveentities_string'])) { $query_where[] = getEntitiesRestrictRequest("AND", 'task'); } if (is_array($task_ids) and count($task_ids) > 0) { $query_where[] = "AND task.`id` IN (" . implode(",", $task_ids) . ")"; } // quickly filter empty WHERE entry $query_where = array_filter($query_where); $query_fields = array(array('task.id', 'task.`id`'), array('task.name', 'task.`name`'), array('job.id', 'job.`id`'), array('job.name', 'job.`name`'), array('job.method', 'job.`method`'), array('job.targets', 'job.`targets`')); $fieldmap = array(); foreach ($query_fields as $index => $key) { $fieldmap[$key[0]] = $index; } $query_select = array(); foreach ($query_fields as $index => $key) { $query_select[] = $key[1] . " AS '" . $key[0] . "'"; } $query_joins = array(); $query_joins['task'] = implode("\n", array("INNER JOIN `glpi_plugin_fusioninventory_tasks` as task", " ON job.`plugin_fusioninventory_tasks_id` = task.`id`", " AND task.`is_active` = 1")); $data_structure = array('query' => implode("\n", array("SELECT", implode(",\n", $query_select), "FROM `glpi_plugin_fusioninventory_taskjobs` as job", implode("\n", $query_joins), implode("\n", $query_where))), 'result' => null); $data_structure['result'] = $DB->query($data_structure['query']); //Results grouped by tasks > jobs > jobstates $logs = array(); //Target cache (used to speed up data formatting) $targets_cache = array(); $expanded = array(); if (isset($_SESSION['plugin_fusioninventory_tasks_expanded'])) { $expanded = $_SESSION['plugin_fusioninventory_tasks_expanded']; } while ($result = $data_structure['result']->fetch_row()) { $task_id = $result[$fieldmap['task.id']]; if (!array_key_exists($task_id, $logs)) { $logs[$task_id] = array('task_name' => $result[$fieldmap['task.name']], 'task_id' => $result[$fieldmap['task.id']], 'expanded' => false, 'jobs' => array()); } if (isset($expanded[$task_id])) { $logs[$task_id]['expanded'] = $expanded[$task_id]; } $job_id = $result[$fieldmap['job.id']]; $jobs_handle =& $logs[$task_id]['jobs']; if (!array_key_exists($job_id, $jobs_handle)) { $jobs_handle[$job_id] = array('name' => $result[$fieldmap['job.name']], 'id' => $result[$fieldmap['job.id']], 'method' => $result[$fieldmap['job.method']], 'targets' => array()); } $targets = importArrayFromDB($result[$fieldmap['job.targets']]); $targets_handle =& $jobs_handle[$job_id]['targets']; $agent_state_types = array('agents_prepared', 'agents_cancelled', 'agents_running', 'agents_success', 'agents_error', 'agents_notdone'); if ($result[$fieldmap['job.method']] == 'networkinventory') { $pfNetworkinventory = new PluginFusioninventoryNetworkinventory(); foreach ($targets as $keyt => $target) { $item_type = key($target); $items_id = current($target); if ($item_type == 'PluginFusioninventoryIPRange') { unset($targets[$keyt]); // In this case get devices of this iprange $deviceList = $pfNetworkinventory->getDevicesOfIPRange($items_id); $targets = array_merge($targets, $deviceList); } } } foreach ($targets as $target) { $item_type = key($target); $item_id = current($target); $target_id = $item_type . "_" . $item_id; if (isset($targets_cache[$target_id])) { $item = $targets_cache[$target_id]; } else { $item = new $item_type(); $item->getFromDB($item_id); $targets_cache[$target_id] = $item; } $targets_handle[$target_id] = array('id' => $item->fields['id'], 'name' => $item->fields['name'], 'type_name' => $item->getTypeName(), 'item_link' => $item->getLinkUrl(), 'counters' => array(), 'agents' => array()); // create agent states counter lists foreach ($agent_state_types as $type) { $targets_handle[$target_id]['counters'][$type] = array(); } } } // Query fields mapping used to easily select fields by name $query_fields = array(array('task.id', 'task.`id`'), array('task.name', 'task.`name`'), array('job.id', 'job.`id`'), array('job.name', 'job.`name`'), array('job.method', 'job.`method`'), array('agent.id', 'agent.`id`'), array('agent.name', 'agent.`name`'), array('run.id', 'run.`id`'), array('run.itemtype', 'run.`itemtype`'), array('run.items_id', 'run.`items_id`'), array('run.state', 'run.`state`'), array('log.last_date', 'log.`date`'), array('log.last_timestamp', 'UNIX_TIMESTAMP(log.`date`)'), array('log.last_id', 'log.`id`'), array('log.last_comment', 'log.`comment`')); $fieldmap = array(); foreach ($query_fields as $index => $key) { $fieldmap[$key[0]] = $index; } $query_select = array(); foreach ($query_fields as $index => $key) { $query_select[] = $key[1] . " AS '" . $key[0] . "'"; } $query_joins = array(); $query_joins['max_run'] = implode("\n", array("INNER JOIN (", " SELECT", " MAX(run.`id`) AS max_id,", " run.`plugin_fusioninventory_agents_id`,", " run.`plugin_fusioninventory_taskjobs_id`,", " run.`items_id`, run.`itemtype`,", " MAX(log.`id`) AS max_log_id", " FROM `glpi_plugin_fusioninventory_taskjobstates` AS run", " LEFT JOIN `glpi_plugin_fusioninventory_taskjoblogs` AS log", " ON log.`plugin_fusioninventory_taskjobstates_id` = run.`id`", " GROUP BY", " run.`plugin_fusioninventory_agents_id`,", " run.`plugin_fusioninventory_taskjobs_id`,", " run.`items_id`, run.`itemtype`", ") max_run ON max_run.`plugin_fusioninventory_agents_id` = agent.`id`")); $query_joins['run'] = implode("\n", array("INNER JOIN `glpi_plugin_fusioninventory_taskjobstates` AS run", " ON max_run.`max_id` = run.`id`")); $query_joins['log'] = implode("\n", array("LEFT JOIN `glpi_plugin_fusioninventory_taskjoblogs` as log", " ON log.`id` = max_run.`max_log_id`")); $query_joins['job'] = implode("\n", array("INNER JOIN `glpi_plugin_fusioninventory_taskjobs` AS job", " ON job.`id` = run.`plugin_fusioninventory_taskjobs_id`")); $query_joins['task'] = implode("\n", array("INNER JOIN `glpi_plugin_fusioninventory_tasks` as task", " ON job.`plugin_fusioninventory_tasks_id` = task.`id`")); $queries = array(); /* * Get latest jobstates for agents */ $queries['1_last_runs'] = array('query' => implode(" \n", array("SELECT", implode(",\n", $query_select), "FROM `glpi_plugin_fusioninventory_agents` AS agent", implode("\n", $query_joins), implode("\n", $query_where), "GROUP BY job.`id`, agent.`id`, run.`id`")), 'result' => null); /* * Get last finished jobstates (ie. `state` >= 3) */ $query_joins['max_run'] = implode("\n", array("INNER JOIN (", " SELECT", " MAX(run.`id`) AS max_id,", " run.`plugin_fusioninventory_agents_id`,", " run.`plugin_fusioninventory_taskjobs_id`,", " run.`items_id`, run.`itemtype`,", " MAX(log.`id`) AS max_log_id", " FROM `glpi_plugin_fusioninventory_taskjobstates` AS run", " LEFT JOIN `glpi_plugin_fusioninventory_taskjoblogs` AS log", " ON log.`plugin_fusioninventory_taskjobstates_id` = run.`id`", " WHERE run.`state` IN ( " . implode(",", array(PluginFusioninventoryTaskjobstate::FINISHED, PluginFusioninventoryTaskjobstate::IN_ERROR)) . " )", " GROUP BY", " run.`plugin_fusioninventory_agents_id`,", " run.`plugin_fusioninventory_taskjobs_id`,", " run.`items_id`, run.`itemtype`", ") max_run ON max_run.`plugin_fusioninventory_agents_id` = agent.`id`")); $queries['2_finished_runs'] = array('query' => implode(" \n", array("SELECT", implode(",\n", $query_select), "FROM `glpi_plugin_fusioninventory_agents` AS agent", implode("\n", $query_joins), implode("\n", $query_where), "GROUP BY job.`id`, agent.`id`, run.`id`")), 'result' => null); $query_chrono = array("start" => microtime(true), "end" => 0); ksort($queries); foreach ($queries as $query_name => $contents) { $queries[$query_name]['result'] = $DB->query($contents['query']); $query_chrono['end'] = microtime(true); // For debug only //if ($debug_mode) { // file_put_contents("/tmp/glpi_".$query_name.".sql",$contents['query']); //} } $agents = array(); $format_chrono = array("start" => microtime(true), "end" => 0); foreach ($queries as $query_name => $contents) { if (!is_null($contents['result'])) { while ($result = $contents['result']->fetch_row()) { // We need to check if the results are consistent with the view's structure gathered // by the first query $task_id = $result[$fieldmap['task.id']]; //if (!array_key_exists($task_id, $logs)) { if (!isset($logs[$task_id])) { continue; } $job_id = $result[$fieldmap['job.id']]; $jobs =& $logs[$task_id]['jobs']; if (!isset($jobs[$job_id])) { continue; } $target_id = $result[$fieldmap['run.itemtype']] . '_' . $result[$fieldmap['run.items_id']]; $targets =& $jobs[$job_id]['targets']; if (!isset($targets[$target_id])) { continue; } $counters =& $targets[$target_id]['counters']; $agent_id = $result[$fieldmap['agent.id']]; $agents[$agent_id] = $result[$fieldmap['agent.name']]; if (!isset($targets[$target_id]['agents'][$agent_id])) { $targets[$target_id]['agents'][$agent_id] = array(); } $agent_state = ''; // Update counters switch ($result[$fieldmap['run.state']]) { case PluginFusioninventoryTaskjobstate::CANCELLED: // We put this agent in the cancelled counter if it does not have any other job // states. if (!isset($counters['agents_prepared'][$agent_id]) and !isset($counters['agents_running'][$agent_id])) { $counters['agents_cancelled'][$agent_id] = 1; $agent_state = 'cancelled'; } break; case PluginFusioninventoryTaskjobstate::PREPARED: // We put this agent in the prepared counter if it has not yet completed any job. $counters['agents_prepared'][$agent_id] = 1; $agent_state = 'prepared'; break; case PluginFusioninventoryTaskjobstate::SERVER_HAS_SENT_DATA: case PluginFusioninventoryTaskjobstate::AGENT_HAS_SENT_DATA: // This agent is running so it must not be in any other counter foreach ($agent_state_types as $type) { if (isset($counters[$type][$agent_id])) { unset($counters[$type][$agent_id]); } } $counters['agents_running'][$agent_id] = 1; $agent_state = 'running'; break; case PluginFusioninventoryTaskjobstate::IN_ERROR: if (isset($counters['agents_success'][$agent_id])) { unset($counters['agents_success'][$agent_id]); } $counters['agents_error'][$agent_id] = 1; $agent_state = 'error'; if (isset($counters['agents_notdone'][$agent_id])) { unset($counters['agents_notdone'][$agent_id]); } break; case PluginFusioninventoryTaskjobstate::FINISHED: if (isset($counters['agents_error'][$agent_id])) { unset($counters['agents_error'][$agent_id]); } $counters['agents_success'][$agent_id] = 1; $agent_state = 'success'; if (isset($counters['agents_notdone'][$agent_id])) { unset($counters['agents_notdone'][$agent_id]); } break; } if (!isset($counters['agents_error'][$agent_id]) and !isset($counters['agents_success'][$agent_id])) { $counters['agents_notdone'][$agent_id] = 1; } if (isset($counters['agents_running'][$agent_id]) or isset($counters['agents_prepared'][$agent_id])) { unset($counters['agents_cancelled'][$agent_id]); } $targets[$target_id]['agents'][$agent_id][] = array('agent_id' => $agent_id, 'numstate' => $result[$fieldmap['run.state']], 'state' => $agent_state, 'jobstate_id' => $result[$fieldmap['run.id']], 'last_log_id' => $result[$fieldmap['log.last_id']], 'last_log_date' => $result[$fieldmap['log.last_date']], 'timestamp' => $result[$fieldmap['log.last_timestamp']], 'last_log' => $result[$fieldmap['log.last_comment']]); } } } $format_chrono['end'] = microtime(true); if ($debug_mode) { function tmp_display_log($log) { return "ID:" . $log['task_id'] . "(" . $log['task_name'] . ")"; } if (PluginFusioninventoryConfig::isExtradebugActive()) { Toolbox::logDebug(array("tasks" => implode(',', array_map('tmp_display_log', $logs)), "row count" => count($logs), "Joblogs Query" => self::FormatChrono($query_chrono), "Format logs results" => self::FormatChrono($format_chrono))); } } return array('tasks' => $logs, 'agents' => $agents); }
static function cronWakeupAgents($crontask) { global $DB; $wakeupArray = array(); $tasks = array(); //Get the maximum number of agent to wakeup, //as allowed in the general configuration $config = new PluginFusioninventoryConfig(); $maxWakeUp = $config->getValue('wakeup_agent_max'); $counter = 0; $continue = true; //Get all active timeslots $timeslot = new PluginFusioninventoryTimeslot(); $timeslots = $timeslot->getCurrentActiveTimeslots(); if (empty($timeslots)) { $query_timeslot = ''; } else { $query_timeslot = "OR (`plugin_fusioninventory_timeslots_id` IN (" . implode(',', $timeslots) . "))"; } //Get all active task requiring an agent wakeup //Check all tasks without timeslot or task with a current active timeslot $query = "SELECT `id`, `wakeup_agent_counter`, `wakeup_agent_time`, `last_agent_wakeup` \n FROM `glpi_plugin_fusioninventory_tasks` \n WHERE `wakeup_agent_time` > 0 \n AND `wakeup_agent_counter` > 0\n AND `is_active`='1' \n AND ((`plugin_fusioninventory_timeslots_id`='0') \n {$query_timeslot})"; foreach ($DB->request($query) as $task) { if (!is_null($task['wakeup_agent_time'])) { //Do not wake up is last wake up in inferior to the minimum wake up interval $interval = time() - strtotime($task['last_agent_wakeup']); if ($interval < $task['wakeup_agent_time'] * MINUTE_TIMESTAMP) { continue; } } //For each task, get a number of taskjobs at the PREPARED state //(the maximum is defined in wakeup_agent_counter) $query_states = "SELECT `taskjobstates`.`plugin_fusioninventory_agents_id`, \n `tasks`.`id` as `taskID`, \n `tasks`.`wakeup_agent_time`,\n `tasks`.`last_agent_wakeup`\n FROM `glpi_plugin_fusioninventory_taskjobstates` as `taskjobstates`,\n `glpi_plugin_fusioninventory_taskjobs` as `taskjobs`\n LEFT JOIN `glpi_plugin_fusioninventory_tasks` as `tasks` \n ON `tasks`.`id`=`taskjobs`.`plugin_fusioninventory_tasks_id`\n WHERE `tasks`.`id`='" . $task['id'] . "' \n AND `taskjobs`.`id`=`taskjobstates`.`plugin_fusioninventory_taskjobs_id` \n AND `taskjobstates`.`state`='" . PluginFusioninventoryTaskjobstate::PREPARED . "' \n ORDER BY `taskjobstates`.`id` ASC LIMIT " . $task['wakeup_agent_counter']; foreach ($DB->request($query_states) as $state) { $agents_id = $state['plugin_fusioninventory_agents_id']; //Check if agent is already added to the list of agents to wake up if (!isset($wakeupArray[$agents_id])) { //This agent must be woken up $wakeupArray[$agents_id] = $agents_id; $counter++; } //Store task ID if (!in_array($state['taskID'], $tasks)) { $tasks[] = $state['taskID']; } //Do not process more than the maximum number of wakeup allowed in the configuration if ($counter >= $maxWakeUp) { if (PluginFusioninventoryConfig::isExtradebugActive()) { Toolbox::logDebug(__("Maximum number of agent wakeup reached", 'fusioninventory') . ":" . $maxWakeUp); } $continue = false; break; } } //We've reached the maximum number of agents to wake up ! if (!$continue) { break; } } //Number of agents successfully woken up $wokeup = 0; $myTask = new PluginFusioninventoryTask(); if (!empty($tasks)) { //Update last wake up time each task $query_lastrun = "UPDATE `glpi_plugin_fusioninventory_tasks` \n SET `last_agent_wakeup`='" . $_SESSION['glpi_currenttime'] . "' \n WHERE `id` IN (" . implode(",", $tasks) . ")"; $DB->query($query_lastrun); $agent = new PluginFusioninventoryAgent(); //Try to wake up agents one by one foreach ($wakeupArray as $ID => $value) { $agent->getFromDB($ID); if ($agent->wakeUp()) { $wokeup++; } } } $crontask->addVolume($wokeup); return true; }
function __construct() { if (PluginFusioninventoryConfig::isExtradebugActive()) { $this->logFile = GLPI_LOG_DIR . '/fusioninventorycommunication.log'; } }
/** * Add logs * * @param $p_logs logs to write * * @return nothing (write text in log file) **/ static function addLog($p_logs) { if ($_SESSION['glpi_use_mode'] == Session::DEBUG_MODE) { if (PluginFusioninventoryConfig::isExtradebugActive()) { file_put_contents(GLPI_LOG_DIR . '/pluginFusioninventory-communication.log', "\n" . time() . ' : ' . $p_logs, FILE_APPEND); } } }