Completed
Push — master ( c091a3...52a46f )
by Petrică
02:24
created

NotifyCommand::getConfiguration()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 6
ccs 0
cts 5
cp 0
rs 9.4285
cc 1
eloc 3
nc 1
nop 1
crap 2
1
<?php
2
/**
3
 * Created by PhpStorm.
4
 * User: Petrica
5
 * Date: 3/22/2016
6
 * Time: 22:45
7
 */
8
namespace Petrica\StatsdSystem\Command;
9
10
use Domnikl\Statsd\Client;
11
use Domnikl\Statsd\Connection\UdpSocket;
12
use Petrica\StatsdSystem\Config\ConfigLoader;
13
use Petrica\StatsdSystem\Gauge\GaugeInterface;
14
use Symfony\Component\Console\Command\Command;
15
use Symfony\Component\Console\Input\InputArgument;
16
use Symfony\Component\Console\Input\InputInterface;
17
use Symfony\Component\Console\Input\InputOption;
18
use Symfony\Component\Console\Output\OutputInterface;
19
20
class NotifyCommand extends Command
21
{
22
    /**
23
     * @var Client
24
     */
25
    protected $statsd = null;
26
27
    /**
28
     * Instantiated gauges
29
     *
30
     * @var array
31
     */
32
    protected $gauges = null;
33
34
    /**
35
     * @var null
36
     */
37
    protected $config = null;
38
39
    protected function configure()
40
    {
41
        $this
42
            ->setName('statsd:notify')
43
            ->setDescription('Collect and send defined gauges to statsd server')
44
            ->addArgument(
45
                'config',
46
                InputArgument::REQUIRED,
47
                'Path to yaml configuration file.'
48
            )
49
            ->addOption(
50
                'statsd-host',
51
                null,
52
                InputOption::VALUE_OPTIONAL,
53
                'Statsd server hostname',
54
                'localhost'
55
            )
56
            ->addOption(
57
                'statsd-port',
58
                null,
59
                InputOption::VALUE_OPTIONAL,
60
                'Statsd server port',
61
                '8125'
62
            )
63
            ->addOption(
64
                'statsd-namespace',
65
                null,
66
                InputOption::VALUE_OPTIONAL,
67
                'Gauge namespace sent to statsd',
68
                'system'
69
            )
70
            ->addOption(
71
                'iterations',
72
                null,
73
                InputOption::VALUE_OPTIONAL,
74
                'The number of times the job collects stats and sends them to statsd server before exiting.',
75
                3600
76
            );
77
    }
78
79
    /**
80
     * @param InputInterface $input
81
     * @param OutputInterface $output
82
     */
83
    protected function execute(InputInterface $input, OutputInterface $output)
84
    {
85
        $config = $this->getConfiguration($input);
86
        $gauges = $this->getGauges($config);
87
        $statsd = $this->getStatsd($input);
88
89
        $iterations = $input->getOption('iterations');
90
        $count = 0;
91
        while($count < $iterations)
92
        {
93
            foreach($gauges as $path => $gauge) {
94
                // Sampling period attained for current gauge?
95
                if (fmod($count, $gauge->getSamplingPeriod()) == 0) {
96
                    $value = $gauge->getValue();
97
                    if (null !== $value) {
98
                        $statsd->gauge($path, $value);
99
                    }
100
101
                    if ($input->getOption('verbose')) {
102
                        $output->writeln(sprintf('%s: %s', $path, $gauge->getValue()));
103
                    }
104
                }
105
            }
106
107
            sleep(1);
108
            $count ++;
109
        }
110
    }
111
112
    /**
113
     * Statically cache statsd client and return a statsd client
114
     *
115
     * @param InputInterface $input
116
     * @return Client
117
     */
118
    protected function getStatsd(InputInterface $input)
119
    {
120
        if (null === $this->statsd) {
121
            $connection = new UdpSocket(
122
                $input->getOption('statsd-host'),
123
                $input->getOption('statsd-port')
124
            );
125
            $this->statsd = new Client(
126
                $connection,
127
                $input->getOption('statsd-namespace')
128
            );
129
        }
130
131
        return $this->statsd;
132
    }
133
134
    /**
135
     * Instantiate selected gauges
136
     *
137
     * @param array $config
138
     * @return GaugeInterface[] array
139
     */
140
    protected function getGauges($config)
141
    {
142
        if (null === $this->gauges) {
143
            $this->gauges = array();
144
145
            foreach ($config as $path => $details) {
146
                $className = $details['class'];
147
                if (class_exists($className)) {
148
                    $reflection = new \ReflectionClass($className);
149
150
                    if ($reflection->getConstructor()) {
151
                        $this->gauges[$path] = $reflection->newInstanceArgs(
152
                            $details['arguments'] ? $details['arguments'] : array());
153
                    }
154
                    else {
155
                        $this->gauges[$path] = $reflection->newInstance();
156
                    }
157
                }
158
                else {
159
                    throw new \RuntimeException(sprintf(
160
                        'Class does not exists %s'
161
                    ), $className);
162
                }
163
            }
164
165
            if (empty($this->gauges)) {
166
                throw new \RuntimeException(
167
                    sprintf('No gauges found for provided string %s', $input->getArgument('gauges-class'))
168
                );
169
            }
170
        }
171
172
        return $this->gauges;
173
    }
174
175
    /**
176
     * Read Yaml configuration file
177
     * and returns array map
178
     *
179
     * @param InputInterface $input
180
     * @return array
181
     */
182
    protected function getConfiguration(InputInterface $input)
183
    {
184
        $loader = new ConfigLoader($input->getArgument('config'));
185
186
        return $loader->load();
187
    }
188
}
189