FileParserCommand   A
last analyzed

Complexity

Total Complexity 9

Size/Duplication

Total Lines 111
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 8

Importance

Changes 0
Metric Value
wmc 9
lcom 1
cbo 8
dl 0
loc 111
rs 10
c 0
b 0
f 0

4 Methods

Rating   Name   Duplication   Size   Complexity  
A configure() 0 20 1
B execute() 0 33 4
A getEvents() 0 14 2
A createClient() 0 16 2
1
<?php
2
3
namespace SegmentIO\Cli\Command;
4
5
use GuzzleHttp\Message\Response;
6
use GuzzleHttp\Stream\Stream;
7
use GuzzleHttp\Subscriber\Mock;
8
use SegmentIO\Client;
9
use Symfony\Component\Filesystem\Filesystem;
10
use Symfony\Component\Console\Command\Command;
11
use Symfony\Component\Console\Input\InputArgument;
12
use Symfony\Component\Console\Input\InputInterface;
13
use Symfony\Component\Console\Input\InputOption;
14
use Symfony\Component\Console\Output\OutputInterface;
15
16
/**
17
 * FileParserCommand Class
18
 *
19
 * @author Keith Kirk <[email protected]>
20
 */
21
class FileParserCommand extends Command
22
{
23
    /**
24
     * {@inhertDoc}
25
     */
26
    protected function configure()
27
    {
28
        $this
29
            ->setName('parse')
30
            ->setDescription('Parses a log file and sends logged events to the Segment.io API')
31
            ->addArgument('write_key', InputArgument::REQUIRED, 'The Segment.io API Write Key', null)
32
            ->addOption(
33
               'file',
34
               null,
35
               InputOption::VALUE_OPTIONAL,
36
               'The file to parse for Segment.io events',
37
               sys_get_temp_dir() . "/segment-io.log"
38
            )
39
            ->addOption(
40
                'debug',
41
                null,
42
                InputOption::VALUE_NONE,
43
                'Debug mode keeps logs from being removed and does not send the data to Segment.io'
44
            );
45
    }
46
47
    /**
48
     * {@inheritDoc}
49
     */
50
    protected function execute(InputInterface $input, OutputInterface $output)
51
    {
52
        $key   = $input->getArgument('write_key');
53
        $file  = $input->getOption('file');
54
        $debug = $input->getOption('debug');
55
56
        $client     = $this->createClient($key, $debug);
57
        $filesystem = new Filesystem();
58
59
        if (!$filesystem->exists($file)) {
60
            throw new \RuntimeException('The specified file does not exist!');
61
        }
62
63
        $temp = sys_get_temp_dir() . sprintf("/segment-io-%s.log", uniqid());
64
        $filesystem->rename($file, $temp);
65
66
        $events = $this->getEvents($temp);
67
        $output->writeln(sprintf("<info>Found %s events in the log to Send</info>", sizeof($events)));
68
        if (!sizeof($events)) {
69
            return 0;
70
        }
71
72
        $batches = array_chunk(array_filter($events), 100);
73
        foreach ($batches as $batch) {
74
            $client->import(['batch' => $batch]);
75
        }
76
77
        $output->writeln(sprintf("<comment>Sent %s batches to Segment.io</comment>", sizeof($batches)));
78
79
        $filesystem->remove($temp);
80
81
        return 0;
82
    }
83
84
85
    /**
86
     * Parses the Log file and returns an array of events to send to Segment.io
87
     *
88
     * @param  string $file The log file
89
     *
90
     * @return array
91
     */
92
    private function getEvents($file)
93
    {
94
        $contents = file_get_contents($file);
95
        $events   = explode("\n", $contents, -1);
96
97
        $events = array_map(function($event) {
98
            $event = json_decode($event, true);
99
            if (!empty($event)) {
100
                return $event;
101
            }
102
        }, $events);
103
104
        return array_filter($events);
105
    }
106
107
    /**
108
     * Creates a SegmentIO\Client
109
     *
110
     * @param  string  $key   The Segment.io API Write Key
111
     * @param  boolean $debug Whether or not to use a MockAdapater
112
     *
113
     * @return Client
114
     */
115
    private function createClient($key, $debug = false)
116
    {
117
        $client = new Client(['write_key' => $key, 'batching' => false]);
118
119
        if ($debug) {
120
            $stream = Stream::factory(json_encode(['success' => true]));
121
            $mock   = new Mock([
122
                new Response(200, [], $stream),
123
            ]);
124
125
            $client->getEmitter()->attach($mock);
126
        }
127
128
129
        return $client;
130
    }
131
}
132