Example #1
0
 /**
  * Constructor
  *
  * @param   \Scalr_Environment  $env           The environment
  * @param   string              $ccId          The identifier of the cost center which is assigned
  * @param   string              $oldCcId       The identifier of the old cost center which is replaced
  */
 public function __construct(Scalr_Environment $env, $ccId, $oldCcId)
 {
     parent::__construct();
     array_push($this->ccs, $ccId, $oldCcId);
     $ccName = AccountTagEntity::fetchName($ccId, TagEntity::TAG_ID_COST_CENTRE);
     $oldCcName = AccountTagEntity::fetchName($oldCcId, TagEntity::TAG_ID_COST_CENTRE);
     $this->message = sprintf("User %s replaced cost center '%s' with '%s' in the enviroment '%s' id:%d", strip_tags($this->getUserEmail()), strip_tags($oldCcName), strip_tags($ccName), strip_tags($env->name), $env->id);
     $this->messageToHash = sprintf('%s|%s|%s|%s|%s', $this->timelineEvent->dtime->format('Y-m-d'), $oldCcId, $ccId, $env->id, $this->getUserEmail());
 }
Example #2
0
 /**
  * Constructor
  *
  * @param   \DBFarm    $farm          The DBFarm instance
  * @param   string     $projectId     The uuid of the project
  */
 public function __construct(DBFarm $farm, $projectId)
 {
     parent::__construct();
     $projectEntity = ProjectEntity::findPk($projectId);
     $this->projects[] = $projectId;
     if ($projectEntity) {
         $this->ccs[] = $projectEntity->ccId;
         $projectName = $projectEntity->name;
     } else {
         $projectName = AccountTagEntity::fetchName($projectId, TagEntity::TAG_ID_PROJECT);
     }
     $this->message = sprintf("User %s assigned a new farm '%s' id:%d to the project '%s'", strip_tags($this->getUserEmail()), strip_tags($farm->Name), $farm->ID, strip_tags($projectName));
     $this->messageToHash = sprintf('%s|%s|%s|%s', $this->timelineEvent->dtime->format('Y-m-d'), $this->getUserEmail(), $farm->ID, $projectId);
 }
Example #3
0
 /**
  * Constructor
  *
  * @param   \DBFarm    $farm              The DBFarm instance
  * @param   string     $projectId         The identifier of the project to assign
  * @param   string     $oldProjectId      The identifier of the old project which is replaced
  */
 public function __construct(DBFarm $farm, $projectId, $oldProjectId)
 {
     parent::__construct();
     array_push($this->projects, $projectId, $oldProjectId);
     $projectEntity = ProjectEntity::findPk($projectId);
     if ($projectEntity) {
         $this->ccs[$projectEntity->ccId] = $projectEntity->ccId;
         $projectName = $projectEntity->name;
     } else {
         $projectName = AccountTagEntity::fetchName($projectId, TagEntity::TAG_ID_PROJECT);
     }
     $oldProjectEntity = ProjectEntity::findPk($oldProjectId);
     if ($oldProjectEntity) {
         $this->ccs[$oldProjectEntity->ccId] = $oldProjectEntity->ccId;
         $oldProjectName = $oldProjectEntity->name;
     } else {
         $oldProjectName = AccountTagEntity::fetchName($oldProjectId, TagEntity::TAG_ID_PROJECT);
     }
     $this->message = sprintf("User %s replaced project '%s' with project '%s' in the farm '%s' id:%d", strip_tags($this->getUserEmail()), strip_tags($oldProjectName), strip_tags($projectName), strip_tags($farm->Name), $farm->ID);
     $this->messageToHash = sprintf('%s|%s|%s|%s|%s', $this->timelineEvent->dtime->format('Y-m-d'), $this->getUserEmail(), $oldProjectId, $projectId, $farm->ID);
 }
Example #4
0
 /**
  * Gets farm role with top cost
  *
  * @param array $farmRoles Array of farm roles
  * @return array Returns farm role top spender
  */
 private function getFarmRoleTopSpender(array $farmRoles)
 {
     $max = 0;
     foreach ($farmRoles as $farmRoleId => $farmRole) {
         if ($max <= $farmRole['cost']) {
             $max = $farmRole['cost'];
             $maxId = $farmRoleId;
         }
     }
     $result = ['id' => $maxId, 'alias' => AccountTagEntity::fetchName($maxId, TagEntity::TAG_ID_FARM_ROLE), 'periodTotal' => $farmRoles[$maxId]['cost'], 'platform' => key($farmRoles[$maxId]['data'])];
     return $result;
 }
Example #5
0
 /**
  * Synchronizes the account level tag value
  *
  * It does not verify itself whether the cost analytics service is enabled
  *
  * @param   int     $accountId    The identifier of the client's account
  * @param   int     $tagId        The identifier of the clould analytics tag
  * @param   string  $valueId      The identifier of the tag's value
  * @param   string  $valueName    The name of the tag's value
  */
 public function syncValue($accountId, $tagId, $valueId, $valueName)
 {
     if ($accountId === null) {
         $accountId = 0;
     }
     $tag = AccountTagEntity::findPk($accountId, $tagId, $valueId);
     if (!$tag instanceof AccountTagEntity) {
         $tag = new AccountTagEntity();
         $tag->accountId = $accountId;
         $tag->tagId = $tagId;
         $tag->valueId = $valueId;
         $tag->valueName = $valueName;
     } else {
         if ($tag->valueName != $valueName) {
             $tag->valueName = $valueName;
             if ($tagId == TagEntity::TAG_ID_FARM) {
                 foreach ($this->db->GetAll("\n                    SELECT fr.id AS farm_role_id, fr.alias\n                    FROM farm_roles fr\n                    WHERE fr.farmid = ?\n                ", [$valueId]) as $v) {
                     //Updates all related farm roles
                     $this->syncValue($accountId, TagEntity::TAG_ID_FARM_ROLE, $v['farm_role_id'], sprintf('%s', $v['alias']));
                 }
             }
         } else {
             $ignoreupdate = true;
         }
     }
     if (!isset($ignoreupdate)) {
         $tag->save();
     }
 }
Example #6
0
 /**
  * Gets cost analytics for environment scope
  *
  * @param   Scalr_Environment  $env       Current environment
  * @param   string             $mode      The mode (week, month, quarter, year)
  * @param   string             $startDate The start date of the period in UTC ('Y-m-d')
  * @param   string             $endDate   The end date of the period in UTC ('Y-m-d')
  * @return  array     Returns cost analytics data for environment scope
  */
 public function getEnvironmentPeriodData(Scalr_Environment $env, $mode, $startDate, $endDate)
 {
     $analytics = $this->getContainer()->analytics;
     $utcTz = new DateTimeZone('UTC');
     $iterator = ChartPeriodIterator::create($mode, new DateTime($startDate, $utcTz), new DateTime($endDate, $utcTz), 'UTC');
     $start = $iterator->getStart();
     $end = $iterator->getEnd();
     $timelineEvents = $analytics->events->count($iterator->getInterval(), $iterator->getStart(), $iterator->getEnd(), ['envId' => $env->id, 'accountId' => $env->clientId]);
     //Interval which is used in the database query for grouping
     $queryInterval = preg_replace('/^1 /', '', $iterator->getInterval());
     $criteria = ['envId' => $env->id];
     //Requests data for the specified period
     $rawUsage = $this->getFarmData($env->clientId, $criteria, $start, $end, [$queryInterval, TagEntity::TAG_ID_PLATFORM, TagEntity::TAG_ID_FARM], true);
     //Requests data for the previous period
     $rawPrevUsage = $this->getFarmData($env->clientId, $criteria, $iterator->getPreviousStart(), $iterator->getPreviousEnd(), [$queryInterval, TagEntity::TAG_ID_PLATFORM, TagEntity::TAG_ID_FARM], true);
     $max = 5;
     //Calculates top five farms for the specified period
     $top5farms = [];
     $this->otherFarmsQuantity = 0;
     $arr = (new AggregationCollection(['farmId'], ['cost' => 'sum']))->load($rawUsage)->getArrayCopy();
     if (!empty($arr['data']) && count($arr['data']) > $max + 1) {
         $this->otherFarmsQuantity = count($arr['data']) - $max;
         uasort($arr['data'], function ($a, $b) {
             if ($a['cost'] == $b['cost']) {
                 return 0;
             }
             return $a['cost'] < $b['cost'] ? 1 : -1;
         });
         $i = 0;
         foreach ($arr['data'] as $farmId => $v) {
             $top5farms[$farmId] = $farmId;
             if (++$i >= 5) {
                 break;
             }
         }
     }
     $usgByPlatformDetailed = (new AggregationCollection(['period', 'platform'], ['cost' => 'sum']))->load($rawUsage)->calculatePercentage();
     $usgByPlatformPrevDetailed = (new AggregationCollection(['period', 'platform'], ['cost' => 'sum']))->load($rawPrevUsage)->calculatePercentage();
     if (empty($top5farms)) {
         $usgByFarmDetailed = (new AggregationCollection(['period', 'farmId', 'platform'], ['cost' => 'sum']))->load($rawUsage)->calculatePercentage();
         $usgByFarmPrevDetailed = (new AggregationCollection(['period', 'farmId', 'platform'], ['cost' => 'sum']))->load($rawPrevUsage)->calculatePercentage();
     } else {
         $usgByFarmDetailed = new AggregationCollection(['period', 'farmId', 'platform'], ['cost' => 'sum']);
         foreach ($rawUsage as $d) {
             if (!array_key_exists($d['farmId'], $top5farms)) {
                 $d['farmId'] = self::EVERYTHING_ELSE;
             }
             $usgByFarmDetailed->append($d);
         }
         $usgByFarmDetailed->calculatePercentage();
         $usgByFarmPrevDetailed = new AggregationCollection(['period', 'farmId', 'platform'], ['cost' => 'sum']);
         foreach ($rawPrevUsage as $d) {
             if (!array_key_exists($d['farmId'], $top5farms)) {
                 $d['farmId'] = self::EVERYTHING_ELSE;
             }
             $usgByFarmPrevDetailed->append($d);
         }
         $usgByFarmPrevDetailed->calculatePercentage();
     }
     $quarterIterator = $this->getCurrentQuarterIterator();
     $queryQuarterInterval = preg_replace('/^1 /', '', $quarterIterator->getInterval());
     $rawQuarterUsage = $this->getFarmData($env->clientId, $criteria, $quarterIterator->getStart(), $quarterIterator->getEnd(), [TagEntity::TAG_ID_PLATFORM], true);
     $itemsRollingAvg = $this->getRollingAvg(['envId' => $env->id], $queryQuarterInterval, $quarterIterator->getEnd(), $env->clientId, $rawQuarterUsage, ['platform' => 'clouds']);
     $cloudsData = [];
     $farmsData = [];
     $timeline = [];
     $prevPointKey = null;
     foreach ($iterator as $chartPoint) {
         /* @var $chartPoint \Scalr\Stats\CostAnalytics\ChartPointInfo */
         $i = $chartPoint->i;
         $currentPeriodTotal = isset($usgByPlatformDetailed['data'][$chartPoint->key]) ? $usgByPlatformDetailed['data'][$chartPoint->key] : null;
         $ppTotal = isset($usgByPlatformPrevDetailed['data'][$chartPoint->previousPeriodKey]) ? $usgByPlatformPrevDetailed['data'][$chartPoint->previousPeriodKey] : null;
         $pptTotal = isset($usgByPlatformDetailed['data'][$prevPointKey]) ? $usgByPlatformDetailed['data'][$prevPointKey] : null;
         $pointDataTotal = $this->getPointDataArray($currentPeriodTotal, $ppTotal, $pptTotal);
         $timeline[] = ['datetime' => $chartPoint->dt->format('Y-m-d H:00'), 'label' => $chartPoint->label, 'onchart' => $chartPoint->show, 'events' => isset($timelineEvents[$chartPoint->key]) ? $timelineEvents[$chartPoint->key] : null] + $pointDataTotal;
         //Period - Platform - Farms subtotals
         if (!isset($usgByPlatformDetailed['data'][$chartPoint->key]['data'])) {
             foreach ($cloudsData as $platform => $v) {
                 if (!$iterator->isFuture()) {
                     //Previous period details
                     if (isset($usgByPlatformPrevDetailed['data'][$chartPoint->previousPeriodKey]['data'][$platform])) {
                         $pp = $usgByPlatformPrevDetailed['data'][$chartPoint->previousPeriodKey]['data'][$platform];
                     } else {
                         $pp = null;
                     }
                     //Previous point details
                     if (isset($usgByPlatformDetailed['data'][$prevPointKey]['data'][$platform])) {
                         $ppt = $usgByPlatformDetailed['data'][$prevPointKey]['data'][$platform];
                     } else {
                         $ppt = null;
                     }
                     $r = $this->getPointDataArray(null, $pp, $ppt);
                     $cloudsData[$platform]['data'][] = $r;
                 } else {
                     $cloudsData[$platform]['data'][] = null;
                 }
             }
         } else {
             //Initializes with empty values to prevent data shifts on charts.
             if (!isset($usgByPlatformDetailed['data'][$chartPoint->key]['data'])) {
                 $usgByPlatformDetailed['data'][$chartPoint->key]['data'] = [];
             }
             $combined =& $usgByPlatformDetailed['data'][$chartPoint->key]['data'];
             if (!empty($cloudsData)) {
                 foreach ($cloudsData as $platform => $t) {
                     if (!array_key_exists($platform, $combined)) {
                         $combined[$platform] = [];
                     }
                 }
             }
             foreach ($combined as $platform => $v) {
                 //Previous period details
                 if (isset($usgByPlatformPrevDetailed['data'][$chartPoint->previousPeriodKey]['data'][$platform])) {
                     $pp = $usgByPlatformPrevDetailed['data'][$chartPoint->previousPeriodKey]['data'][$platform];
                 } else {
                     $pp = null;
                 }
                 //Previous point details
                 if (isset($usgByPlatformDetailed['data'][$prevPointKey]['data'][$platform])) {
                     $ppt = $usgByPlatformDetailed['data'][$prevPointKey]['data'][$platform];
                 } else {
                     $ppt = null;
                 }
                 if (!isset($cloudsData[$platform]) && $i > 0) {
                     $cloudsData[$platform]['name'] = $platform;
                     //initializes platfrorm legend for the not filled period
                     $cloudsData[$platform]['data'] = array_fill(0, $i, null);
                 }
                 if (!$iterator->isFuture()) {
                     $r = $this->getPointDataArray($v, $pp, $ppt);
                     $cloudsData[$platform]['name'] = $platform;
                     $cloudsData[$platform]['data'][] = $r;
                 } else {
                     $cloudsData[$platform]['data'][] = null;
                 }
             }
         }
         //Period - Farm - Platform subtotal
         if (!isset($usgByFarmDetailed['data'][$chartPoint->key]['data'])) {
             foreach ($farmsData as $farmId => $v) {
                 if (!$iterator->isFuture()) {
                     //Previous period details
                     if (isset($usgByFarmPrevDetailed['data'][$chartPoint->previousPeriodKey]['data'][$farmId])) {
                         $pp = $usgByFarmPrevDetailed['data'][$chartPoint->previousPeriodKey]['data'][$farmId];
                     } else {
                         $pp = null;
                     }
                     //Previous point details
                     if (isset($usgByFarmDetailed['data'][$prevPointKey]['data'][$farmId])) {
                         $ppt = $usgByFarmDetailed['data'][$prevPointKey]['data'][$farmId];
                     } else {
                         $ppt = null;
                     }
                     $r = $this->getPointDataArray(null, $pp, $ppt);
                     $r['clouds'] = [];
                     $r['usageTypes'] = [];
                     $farmsData[$farmId]['data'][] = $r;
                 } else {
                     $farmsData[$farmId]['data'][] = null;
                 }
             }
         } else {
             //Initializes with empty values to prevent data shifts on charts.
             if (!isset($usgByFarmDetailed['data'][$chartPoint->key]['data'])) {
                 $usgByFarmDetailed['data'][$chartPoint->key]['data'] = [];
             }
             $combined =& $usgByFarmDetailed['data'][$chartPoint->key]['data'];
             if (!empty($farmsData)) {
                 foreach ($farmsData as $farmId => $t) {
                     if (!array_key_exists($farmId, $combined)) {
                         $combined[$farmId] = [];
                     }
                 }
             }
             foreach ($combined as $farmId => $v) {
                 //Previous period details
                 if (isset($usgByFarmPrevDetailed['data'][$chartPoint->previousPeriodKey]['data'][$farmId])) {
                     $pp = $usgByFarmPrevDetailed['data'][$chartPoint->previousPeriodKey]['data'][$farmId];
                 } else {
                     $pp = null;
                 }
                 //Previous point details
                 if (isset($usgByFarmDetailed['data'][$prevPointKey]['data'][$farmId])) {
                     $ppt = $usgByFarmDetailed['data'][$prevPointKey]['data'][$farmId];
                 } else {
                     $ppt = null;
                 }
                 if (!isset($farmsData[$farmId]) && $i > 0) {
                     $farmsData[$farmId]['name'] = $this->fetchFarmName($farmId);
                     //initializes project legend for the not filled period
                     $farmsData[$farmId]['data'] = array_fill(0, $i, null);
                 }
                 if (!$iterator->isFuture()) {
                     $r = $this->getPointDataArray($v, $pp, $ppt);
                     // platform data
                     $cloudPlatformData = [];
                     if (!empty($v['data'])) {
                         foreach ($v['data'] as $platform => $pv) {
                             $cloudPlatformData[] = $this->getDetailedPointDataArray($platform, $platform, $pv, isset($pp['data'][$platform]) ? $pp['data'][$platform] : null, isset($ppt['data'][$platform]) ? $ppt['data'][$platform] : null);
                         }
                     }
                     $r['clouds'] = $cloudPlatformData;
                     $farmsData[$farmId]['name'] = $this->fetchFarmName($farmId);
                     $farmsData[$farmId]['data'][] = $r;
                 } else {
                     $farmsData[$farmId]['data'][] = null;
                 }
             }
         }
         $prevPointKey = $chartPoint->key;
     }
     //complete arrays for cloud data and farm data
     $cntpoints = count($timeline);
     foreach ($cloudsData as $platform => $v) {
         if (($j = count($v['data'])) < $cntpoints) {
             while ($j < $cntpoints) {
                 $cloudsData[$platform]['data'][] = null;
                 $j++;
             }
         }
     }
     foreach ($farmsData as $farmId => $v) {
         if (($j = count($v['data'])) < $cntpoints) {
             while ($j < $cntpoints) {
                 $farmsData[$farmId]['data'][] = null;
                 $j++;
             }
         }
     }
     //Subtotals by platforms
     $usage = new AggregationCollection(['platform', 'farmId'], ['cost' => 'sum']);
     //Subtotals by farms
     $usage2 = new AggregationCollection(['farmId' => ['projectId', 'envId'], 'platform'], ['cost' => 'sum']);
     //Subtotals by distr types
     $usage3 = (new AggregationCollection(['distributionType'], ['cost' => 'sum']))->load($this->getFarmData($env->clientId, $criteria, $start, $end, ['distributionType', 'usageType', 'usageItem'], true))->calculatePercentage();
     //Previous period subtotals by platforms
     $prevUsage = new AggregationCollection(['platform', 'farmId'], ['cost' => 'sum']);
     //Previous period subtotals by farms
     $prevUsage2 = new AggregationCollection(['farmId', 'platform'], ['cost' => 'sum']);
     if (empty($top5farms)) {
         //Loads current period
         foreach ($rawUsage as $item) {
             $usage->append($item);
             $usage2->append($item);
         }
         //Loads previous period
         foreach ($rawPrevUsage as $item) {
             $prevUsage->append($item);
             $prevUsage2->append($item);
         }
     } else {
         //Loads current period and aggregates top 5 farms
         foreach ($rawUsage as $item) {
             if (!array_key_exists($item['farmId'], $top5farms)) {
                 $item['farmId'] = self::EVERYTHING_ELSE;
             }
             $usage->append($item);
             $usage2->append($item);
         }
         //Loads previous period and aggregates top 5 farms
         foreach ($rawPrevUsage as $item) {
             if (!array_key_exists($item['farmId'], $top5farms)) {
                 $item['farmId'] = self::EVERYTHING_ELSE;
             }
             $prevUsage->append($item);
             $prevUsage2->append($item);
         }
     }
     //Calculates percentage
     $usage->calculatePercentage();
     $usage2->calculatePercentage();
     $prevUsage->calculatePercentage();
     $prevUsage2->calculatePercentage();
     if ($iterator->getWholePreviousPeriodEnd() != $iterator->getPreviousEnd()) {
         $rawPrevUsageWhole = $this->getFarmData($env->clientId, ['envId' => $env->id], $iterator->getPreviousStart(), $iterator->getWholePreviousPeriodEnd(), [TagEntity::TAG_ID_PLATFORM, TagEntity::TAG_ID_FARM], true);
         //Previous whole period usage subtotals by platform
         $prevUsageWhole = (new AggregationCollection(['platform'], ['cost' => 'sum']))->load($rawPrevUsageWhole);
         //Previous whole period usage subtotals by farm
         $prevUsageWhole2 = (new AggregationCollection(['farmId'], ['cost' => 'sum']))->load($rawPrevUsageWhole);
     } else {
         $prevUsageWhole = $prevUsage;
         $prevUsageWhole2 = $prevUsage2;
     }
     //Build cloud platforms total
     $cloudsTotal = [];
     $it = $usage->getIterator();
     foreach ($it as $platform => $p) {
         $pp = isset($prevUsage['data'][$platform]) ? $prevUsage['data'][$platform] : null;
         $pw = isset($prevUsageWhole['data'][$platform]) ? $prevUsageWhole['data'][$platform] : null;
         $cl = $this->getTotalDataArray($platform, $platform, $p, $pp, $pw, $cloudsData, $iterator);
         $cloudsTotal[] = $cl;
     }
     //Build farms total
     $farmsTotal = [];
     $it = $usage2->getIterator();
     foreach ($it as $farmId => $p) {
         $pp = isset($prevUsage2['data'][$farmId]) ? $prevUsage2['data'][$farmId] : null;
         $pw = isset($prevUsageWhole2['data'][$farmId]) ? $prevUsageWhole2['data'][$farmId] : null;
         $cl = $this->getTotalDataArray($farmId, $this->fetchFarmName($farmId), $p, $pp, $pw, $farmsData, $iterator);
         if ($farmId && $farmId != self::EVERYTHING_ELSE) {
             $userId = AccountTagEntity::fetchName($farmId, TagEntity::TAG_ID_FARM_OWNER);
             if ($userId) {
                 $cl['email'] = AccountTagEntity::fetchName($userId, TagEntity::TAG_ID_USER, $env->clientId);
             }
             if (!empty($p['envId'])) {
                 $cl['environment'] = ['id' => (int) $p['envId'], 'name' => AccountTagEntity::fetchName($p['envId'], TagEntity::TAG_ID_ENVIRONMENT)];
             }
             if (!empty($p['projectId']) && $p['projectId'] !== '00000000-0000-0000-0000-000000000000') {
                 $cl['projectName'] = AccountTagEntity::fetchName($p['projectId'], TagEntity::TAG_ID_PROJECT);
             } else {
                 $cl['projectName'] = 'Unassigned resources';
             }
         }
         if ($it->hasChildren()) {
             $clPlatforms = [];
             foreach ($it->getChildren() as $platform => $c) {
                 $cp = isset($prevUsage2['data'][$farmId]['data'][$platform]) ? $prevUsage2['data'][$farmId]['data'][$platform] : null;
                 $clPlatforms[] = $this->getTotalDataArray($platform, $platform, $c, $cp, null, $cloudsData, $iterator, true);
             }
             $cl['clouds'] = $clPlatforms;
         } else {
             $cl['clouds'] = [];
         }
         $farmsTotal[] = $cl;
     }
     // Build cost dist types total
     $distributionTypesTotal = [];
     foreach ($usage3->getIterator() as $distributionType => $costUsage) {
         $distributionTypesTotal[] = $this->getTotalDataArray($distributionType, $distributionType, $costUsage, null, null, [], null, true);
     }
     $data = ['totals' => ['cost' => round($usage['cost'], 2), 'prevCost' => round($prevUsage['cost'], 2), 'growth' => round($usage['cost'] - $prevUsage['cost'], 2), 'growthPct' => $prevUsage['cost'] == 0 ? null : round(abs(($usage['cost'] - $prevUsage['cost']) / $prevUsage['cost'] * 100), 0), 'clouds' => $cloudsTotal, 'farms' => $farmsTotal, 'distributionTypes' => $distributionTypesTotal, 'trends' => $this->calculateSpendingTrends(['envId' => $env->id], $timeline, $queryInterval, $iterator->getEnd(), $env->clientId), 'forecastCost' => null], 'timeline' => $timeline, 'clouds' => $cloudsData, 'farms' => $farmsData, 'interval' => $queryInterval, 'startDate' => $iterator->getStart()->format('Y-m-d'), 'endDate' => $iterator->getEnd()->format('Y-m-d'), 'previousStartDate' => $iterator->getPreviousStart()->format('Y-m-d'), 'previousEndDate' => $iterator->getPreviousEnd()->format('Y-m-d')];
     if ($iterator->getTodayDate() < $iterator->getEnd()) {
         //Today is in the selected period
         $data['totals']['forecastCost'] = self::calculateForecast($data['totals']['cost'], $start, $end, $prevUsageWhole['cost'], ($data['totals']['growth'] >= 0 ? 1 : -1) * $data['totals']['growthPct'], isset($itemsRollingAvg['rollingAverageDaily']) ? $itemsRollingAvg['rollingAverageDaily'] : null);
     }
     return $data;
 }
Example #7
0
 /**
  * Gets detailed top 5 usage by farms for specified project on date
  *
  * @param   string|null $projectId    The identifier of the project
  * @param   string      $platform     The cloud platform
  * @param   string      $mode         The mode
  * @param   string      $date         The UTC date within period ('Y-m-d H:00')
  * @param   string      $start        The start date of the period in UTC ('Y-m-d')
  * @param   string      $end          The end date of the period in UTC ('Y-m-d')
  * @param   string      $ccId         optional The identifier of the cost center (It is used only when project is null)
  * @return  array       Returns detailed top 5 usage by farms for specified project on date
  * @throws  AnalyticsException
  * @throws  OutOfBoundsException
  */
 public function getProjectFarmsTopUsageOnDate($projectId, $platform, $mode, $date, $start, $end, $ccId = null)
 {
     $projectId = empty($projectId) ? null : $projectId;
     $iterator = new ChartPeriodIterator($mode, $start, $end ?: null, 'UTC');
     //Interval which is used in the database query for grouping
     $queryInterval = preg_replace('/^1 /', '', $iterator->getInterval());
     if ($projectId !== null) {
         $project = ProjectEntity::findPk($projectId);
         if ($project === null) {
             if (empty($ccId)) {
                 throw new AnalyticsException(sprintf("Project %s does not exist. Please provide ccId.", $projectId));
             }
         } else {
             $ccId = $project->ccId;
         }
     }
     //Requests data for the specified period
     $rawUsage = $this->get(['projectId' => $projectId], $iterator->getStart(), $iterator->getEnd(), [$queryInterval, TagEntity::TAG_ID_PLATFORM, TagEntity::TAG_ID_FARM], true);
     //Requests data for the previous period
     $rawPrevUsage = $this->get(['projectId' => $projectId], $iterator->getPreviousStart(), $iterator->getPreviousEnd(), [$queryInterval, TagEntity::TAG_ID_PLATFORM, TagEntity::TAG_ID_FARM], true);
     //We do not need to calculate the percentage here
     $usg = (new AggregationCollection(['period', 'platform', 'farmId' => ['envId']], ['cost' => 'sum']))->load($rawUsage);
     $prevUsg = (new AggregationCollection(['period', 'platform', 'farmId'], ['cost' => 'sum']))->load($rawPrevUsage)->calculatePercentage();
     //Previous chart point
     $prevcp = null;
     //Finds the key for current label
     foreach ($iterator as $chartPoint) {
         //FIXME rewrite search a point
         if ($chartPoint->dt->format('Y-m-d H:00') !== $date) {
             $prevcp = $chartPoint;
             continue;
         }
         $cp = $chartPoint;
         break;
     }
     if (!isset($cp)) {
         throw new OutOfRangeException(sprintf('Requested date (%s) is out of the range. Last point date is %s', $date, isset($prevcp->dt) ? $prevcp->dt->format('Y-m-d H:00') : 'undefined'));
     }
     $result = [];
     //Maximum number of the farms without grouping
     $max = 5;
     $sEverything = self::EVERYTHING_ELSE;
     if (!empty($usg['data'][$cp->key]['data'][$platform]['data'])) {
         $usgFarms = new AggregationCollection(['farmId' => ['envId']], ['cost' => 'sum']);
         $ptr = $usg['data'][$cp->key]['data'][$platform]['data'];
         uasort($ptr, function ($a, $b) {
             if ($a['cost'] == $b['cost']) {
                 return 0;
             }
             return $a['cost'] > $b['cost'] ? -1 : 1;
         });
         //Aggregates farms if its number more then max + 1
         if (count($ptr) > $max + 1) {
             $this->otherFarmsQuantity = count($ptr) - $max;
             $new = [];
             $i = 0;
             foreach ($ptr as $farmId => $v) {
                 $v['cost_percentage'] = round($usg['data'][$cp->key]['data'][$platform]['cost'] == 0 ? 0 : $v['cost'] * 100 / $usg['data'][$cp->key]['data'][$platform]['cost'], 0);
                 if ($i < $max) {
                     $new[$farmId] = $v;
                 } elseif (!isset($new[self::EVERYTHING_ELSE])) {
                     $v['id'] = self::EVERYTHING_ELSE;
                     $new[self::EVERYTHING_ELSE] = $v;
                 } else {
                     $new[self::EVERYTHING_ELSE]['cost'] += $v['cost'];
                 }
                 $i++;
             }
             $new[self::EVERYTHING_ELSE]['cost_percentage'] = round($usg['data'][$cp->key]['data'][$platform]['cost'] == 0 ? 0 : $new[self::EVERYTHING_ELSE]['cost'] * 100 / $usg['data'][$cp->key]['data'][$platform]['cost'], 0);
             $usgFarms->setArray(['data' => $new]);
         } else {
             $usgFarms->setArray($usg['data'][$cp->key]['data'][$platform])->calculatePercentage();
         }
         //Forms result data array
         foreach ($usgFarms->getIterator() as $farmId => $pv) {
             $record = $this->getDetailedPointDataArray($farmId, $this->fetchFarmName($farmId), $pv, isset($prevUsg['data'][$cp->previousPeriodKey]['data'][$platform]['data'][$farmId]) ? $prevUsg['data'][$cp->previousPeriodKey]['data'][$platform]['data'][$farmId] : null, isset($usg['data'][$cp->key]['data'][$platform]['data'][$farmId]) ? $usg['data'][$cp->key]['data'][$platform]['data'][$farmId] : null);
             if ($farmId && $farmId != self::EVERYTHING_ELSE && !empty($pv['envId'])) {
                 $record['environment'] = ['id' => (int) $pv['envId'], 'name' => AccountTagEntity::fetchName($pv['envId'], TagEntity::TAG_ID_ENVIRONMENT)];
             }
             $result[] = $record;
         }
     }
     return ['data' => $result];
 }
Example #8
0
 /**
  * Gets farm with top cost
  *
  * @param array $farms Array of farm roles
  * @return array Returns farm top spender
  */
 private function getFarmTopSpender(array $farms)
 {
     $max = 0;
     foreach ($farms as $farmId => $farm) {
         if ($max <= $farm['cost']) {
             $max = $farm['cost'];
             $maxId = $farmId;
         }
     }
     $result = ['id' => $maxId, 'name' => AccountTagEntity::fetchName($maxId, TagEntity::TAG_ID_FARM), 'periodTotal' => $farms[$maxId]['cost']];
     return $result;
 }