/**
* {@inheritdoc}
* @see \Scalr\System\Zmq\Cron\AbstractTask::enqueue
*/
public function enqueue()
{
$logger = $this->getLogger();
if (!\Scalr::getContainer()->analytics->enabled) {
$logger->info("CA has not been enabled in config!\n");
}
$db = \Scalr::getDb();
$cadb = \Scalr::getContainer()->cadb;
$pricing = new stdPricing();
$quarters = new Quarters(SettingEntity::getQuarters());
$logger->info('Started AnalyticsDemo process');
$tzUtc = new DateTimeZone('UTC');
/* @var $projects stdProject[] */
$projects = [];
/* @var $ccs stdCc[] */
$ccs = [];
/* @var $farms stdFarm[] */
$farms = [];
/* @var $environments stdEnv[] */
$environments = [];
/* @var $farmRoles stdFarmRole[] */
//$farmRoles = [];
//Analytics container
$analytics = \Scalr::getContainer()->analytics;
$logger->debug('CC & PROJECTS ---');
foreach ($analytics->ccs->all(true) as $cc) {
/* @var $cc \Scalr\Stats\CostAnalytics\Entity\CostCentreEntity */
$co = new stdCc();
$co->cc = $cc;
$ccs[$cc->ccId] = $co;
$logger->debug("Cost center: '%s'", $cc->name);
foreach ($cc->getProjects() as $project) {
/* @var $project \Scalr\Stats\CostAnalytics\Entity\ProjectEntity */
$project->loadProperties();
$po = new stdProject();
$po->project = $project;
$po->cc = $co;
$projects[$project->projectId] = $po;
$logger->debug("-- Project: '%s'", $project->name);
}
}
//Ordering cost centers
$number = 0;
foreach ($ccs as $obj) {
$obj->number = $number++;
}
//Ordering projects
$number = 0;
foreach ($projects as $obj) {
$obj->number = $number++;
}
$logger->debug("FARMS ---");
$pastIterations = static::PAST_HOURS_INIT;
//Current time
$start = new DateTime('now', $tzUtc);
$dt = clone $start;
do {
$timestamp = $dt->format('Y-m-d H:00:00');
$period = $quarters->getPeriodForDate($dt->format('Y-m-d'));
$logger->info("Processing time:%s, year:%d, quarter:%d", $timestamp, $period->year, $period->quarter);
//Gets farms for each project
foreach ($projects as $po) {
foreach ($analytics->projects->getFarmsList($po->project->projectId) as $farmId => $farmName) {
if (!isset($farms[$farmId])) {
$fo = new stdFarm();
$fo->farm = \DBFarm::LoadByID($farmId);
$fo->project = $po;
$fo->cc = $po->cc;
//$po->farms[] = $fo;
$farms[$farmId] = $fo;
if (!isset($environments[$fo->farm->EnvID])) {
$eo = new stdEnv();
$eo->env = $fo->farm->getEnvironmentObject();
//$eo->farms = [$farmId => $fo];
$environments[$fo->farm->EnvID] = $eo;
$fo->env = $eo;
} else {
//$environments[$fo->farm->EnvID]->farms[$farmId] = $fo;
$fo->env = $environments[$fo->farm->EnvID];
}
$fo->farmRoles = [];
foreach ($fo->farm->GetFarmRoles() as $farmRole) {
$fro = new stdFarmRole();
$fro->farmRole = $farmRole;
$fro->farm = $fo;
$fro->min = $farmRole->GetSetting(\DBFarmRole::SETTING_SCALING_MIN_INSTANCES);
$fro->max = $farmRole->GetSetting(\DBFarmRole::SETTING_SCALING_MAX_INSTANCES);
$fo->farmRoles[$farmRole->ID] = $fro;
//$farmRoles[$farmRole->ID] = $fro;
}
} else {
$fo = $farms[$farmId];
}
$logger->debug("Farm:'%s':%d from Env:'%s':%d corresponds to Project:'%s' -> CC:'%s'", $fo->farm->Name, $fo->farm->ID, $fo->farm->getEnvironmentObject()->name, $fo->farm->EnvID, $po->project->name, $po->cc->cc->name);
foreach ($fo->farmRoles as $fro) {
/* @var $fro stdFarmRole */
$countInstances = rand(max(1, floor($fro->max * 0.7)), min((int) $fro->max, 2));
$cost = $pricing->getPrice($dt, $fro->farmRole->Platform, $fro->farmRole->CloudLocation, $fro->getInstanceType(), $fo->env->getUrl($fro->farmRole->Platform), PriceEntity::OS_LINUX);
$type = UsageTypeEntity::NAME_COMPUTE_BOX_USAGE;
$costDistType = UsageTypeEntity::COST_DISTR_TYPE_COMPUTE;
$usageTypeEntity = UsageTypeEntity::findOne([['costDistrType' => $costDistType], ['name' => $type]]);
/* @var $usageTypeEntity UsageTypeEntity */
if ($usageTypeEntity === null) {
$usageTypeEntity = new UsageTypeEntity();
$usageTypeEntity->costDistrType = $costDistType;
$usageTypeEntity->name = $type;
$usageTypeEntity->displayName = 'Compute instances';
$usageTypeEntity->save();
}
$item = $fro->getInstanceType();
$usageItemEntity = UsageItemEntity::findOne([['usageType' => $usageTypeEntity->id], ['name' => $item]]);
/* @var $usageItemEntity UsageItemEntity */
if ($usageItemEntity === null) {
$usageItemEntity = new UsageItemEntity();
$usageItemEntity->usageType = $usageTypeEntity->id;
$usageItemEntity->name = $item;
$usageItemEntity->save();
}
//Hourly usage
$rec = new UsageHourlyEntity();
$rec->usageId = \Scalr::GenerateUID();
$rec->accountId = $fro->farm->farm->ClientID;
$rec->ccId = $po->cc->cc->ccId;
$rec->projectId = $po->project->projectId;
$rec->cloudLocation = $fro->farmRole->CloudLocation;
$rec->dtime = new DateTime($timestamp, $tzUtc);
$rec->envId = $fo->farm->EnvID;
$rec->farmId = $fo->farm->ID;
$rec->farmRoleId = $fro->farmRole->ID;
$rec->usageItem = $usageItemEntity->id;
$rec->platform = $fro->farmRole->Platform;
$rec->url = $fo->env->getUrl($fro->farmRole->Platform);
$rec->os = PriceEntity::OS_LINUX;
$rec->num = $countInstances;
$rec->cost = $cost * $countInstances;
$rec->save();
$logger->log(static::PAST_HOURS_INIT > 0 ? 'DEBUG' : 'INFO', "-- role:'%s':%d platform:%s, min:%d - max:%d, cloudLocation:'%s', usageItem:'%s', " . "cost:%0.4f * %d = %0.3f", $fro->farmRole->Alias, $fro->farmRole->ID, $fro->farmRole->Platform, $fro->min, $fro->max, $fro->farmRole->CloudLocation, $usageItemEntity->id, $cost, $countInstances, $rec->cost);
//Update Daily table
$cadb->Execute("\n INSERT usage_d\n SET date = ?,\n platform = ?,\n cc_id = UNHEX(?),\n project_id = UNHEX(?),\n farm_id = ?,\n env_id = ?,\n cost = ?\n ON DUPLICATE KEY UPDATE cost = cost + ?\n ", [$rec->dtime->format('Y-m-d'), $rec->platform, $rec->ccId ? str_replace('-', '', $rec->ccId) : '00000000-0000-0000-0000-000000000000', $rec->projectId ? str_replace('-', '', $rec->projectId) : '00000000-0000-0000-0000-000000000000', $rec->farmId ? $rec->farmId : 0, $rec->envId ? $rec->envId : 0, $rec->cost, $rec->cost]);
//Updates Quarterly Budget
if ($rec->ccId) {
$cadb->Execute("\n INSERT quarterly_budget\n SET year = ?,\n subject_type = ?,\n subject_id = UNHEX(?),\n quarter = ?,\n budget = 1000,\n cumulativespend = ?\n ON DUPLICATE KEY UPDATE cumulativespend = cumulativespend + ?\n ", [$period->year, QuarterlyBudgetEntity::SUBJECT_TYPE_CC, str_replace('-', '', $rec->ccId), $period->quarter, $rec->cost, $rec->cost]);
}
if ($rec->projectId) {
$cadb->Execute("\n INSERT quarterly_budget\n SET year = ?,\n subject_type = ?,\n subject_id = UNHEX(?),\n quarter = ?,\n budget = 1000,\n cumulativespend = ?\n ON DUPLICATE KEY UPDATE cumulativespend = cumulativespend + ?\n ", [$period->year, QuarterlyBudgetEntity::SUBJECT_TYPE_PROJECT, str_replace('-', '', $rec->projectId), $period->quarter, $rec->cost, $rec->cost]);
}
}
unset($fo);
}
}
$dt->modify('-1 hour');
} while ($pastIterations-- > 0);
$dt = clone $start;
$start->modify(sprintf("-%d hour", static::PAST_HOURS_INIT));
$start->setTime(0, 0, 0);
$date = $dt->format('Y-m-d');
$hours = (int) $dt->format('H');
do {
$cadb->Execute("\n INSERT INTO `farm_usage_d` (\n `account_id`,\n `farm_role_id`,\n `usage_item`,\n `cc_id`,\n `project_id`,\n `date`,\n `platform`,\n `cloud_location`,\n `env_id`,\n `farm_id`,\n `role_id`,\n `cost`,\n `min_usage`,\n `max_usage`,\n `usage_hours`,\n `working_hours`)\n SELECT\n `account_id`,\n IFNULL(`farm_role_id`, 0) `farm_role_id`,\n `usage_item`,\n IFNULL(`cc_id`, '') `cc_id`,\n IFNULL(`project_id`, '') `project_id`,\n ? `date`,\n `platform`,\n `cloud_location`,\n IFNULL(`env_id`, 0) `env_id`,\n IFNULL(`farm_id`, 0) `farm_id`,\n IFNULL(`role_id`, 0) `role_id`,\n SUM(`cost`) `cost`,\n (CASE WHEN COUNT(`dtime`) >= ? THEN MIN(`num`) ELSE 0 END) `min_usage`,\n MAX(`num`) `max_usage`,\n SUM(`num`) `usage_hours`,\n COUNT(`dtime`) `working_hours`\n FROM `usage_h` `uh`\n WHERE `uh`.`dtime` BETWEEN ? AND ?\n AND `uh`.`farm_id` > 0\n AND `uh`.`farm_role_id` > 0\n GROUP BY `uh`.`account_id` , `uh`.`farm_role_id` , `uh`.`usage_item`\n ON DUPLICATE KEY UPDATE\n `cost` = VALUES(`cost`),\n `min_usage` = VALUES(`min_usage`),\n `max_usage` = VALUES(`max_usage`),\n `usage_hours` = VALUES(`usage_hours`),\n `working_hours` = VALUES(`working_hours`)\n ", ["{$date} 00:00:00", $hours, "{$date} 00:00:00", "{$date} 23:00:00"]);
$dt->modify('-1 day');
$date = $dt->format('Y-m-d');
$hours = 24;
} while ($dt >= $start);
$logger->info("Finished AnalyticsDemo process");
$logger->info("Memory usage: %0.3f Mb", memory_get_usage() / 1024 / 1024);
return new ArrayObject();
}