source: lliurex-analytics-server/trunk/fuentes/lliurex-analytics-server/usr/lib/analytics-server/analytics/db.php @ 5926

Last change on this file since 5926 was 5926, checked in by mabarracus, 2 years ago

Fixed init script installation & update procedures
Syslog logging
Fixed reconnection when mysql is not available

File size: 13.8 KB
Line 
1<?php
2class DB{
3
4        private $dbhost;
5        private $dbname;
6        private $dbuser;
7        private $dbpass;
8        private $ka_file='/var/run/analyticsd.keepalive';
9        private $alias;
10        public $dbconn;
11
12        function DB(){
13                require_once('config.php');
14                global $dbhost,$dbname,$dbpass,$dbuser,$distros;
15               
16                $this->dbhost=$dbhost;
17                $this->dbname=$dbname;
18                $this->dbpass=$dbpass;
19                $this->dbuser=$dbuser;
20                $this->alias=array();
21                $this->info_distro=json_decode($distros,true);
22                if ($this->info_distro == NULL){
23                    die('Error: Wrong json in Config.php');
24                }
25                $this->init_dates();
26                $this->times=0;
27        }
28        function init_dates(){
29                $this->dates=array();
30                $this->dates['today']=date("Y-m-d");
31                $this->dates['first_current']=date("Y-m-").'01';
32                $this->dates['last_old']=date("Y-m-d",strtotime($this->dates['first_current']." -1 days"));
33                $this->dates['first_old']=date("Y-m-",strtotime($this->dates['today']. "-1 months")).'01';
34                $this->dates['last_very_old']=date("Y-m-d",strtotime($this->dates['first_old']." -1 days"));
35                $this->dates['first_very_old']=date("Y-m-",strtotime($this->dates['first_old']." -1 days")).'01';
36                $this->dates['date_current']="(date between '".$this->dates['first_current']."' and '".$this->dates['today']."')";
37                $this->dates['date_old']="(date between '".$this->dates['first_old']."' and '".$this->dates['last_old']."')";
38                $this->dates['date_very_old']="(date between '".$this->dates['first_very_old']."' and '".$this->dates['last_very_old']."')";
39                $this->dates['date_range_last_three_months']="(date between '".$this->dates['first_very_old']."' and '".$this->dates['today']."')";
40
41        }
42        function connect(){
43                $this->dbconn=new mysqli($this->dbhost, $this->dbuser , $this->dbpass, $this->dbname);
44                if ($this->dbconn->connect_error) {
45                    die('Connect Error:'. $this->dbconn->connect_error);
46                }
47        }
48        function disconnect(){
49                $this->dbconn->close();
50        }
51        function init_trans(){
52                $this->dbconn->autocommit(FALSE);
53                $this->dbconn->begin_transaction(MYSQLI_TRANS_START_READ_WRITE);
54        }
55
56        function send_data($user,$version,$sabor,$apps,$date=''){
57            if ($date == ''){
58                $sql="INSERT INTO tmp_clients(user,version,sabor,status) values ('$user','$version','$sabor',0)";
59            }else{
60                $sql="INSERT INTO tmp_clients(user,version,sabor,status,date) values ('$user','$version','$sabor',0,'$date')";
61            }
62            $retry=1;
63            $done=false;
64            $cli_id=false;
65            while (! $done and $retry < 4){
66                $res=$this->dbconn->query($sql);
67                if ($res){
68                    $cli_id=$this->dbconn->insert_id; 
69                    $done=true;
70                }else{
71                    $retry+=1;
72                    sleep($retry);
73                }
74            }
75            if ($retry == 4 or $cli_id == false)
76                    throw new Exception('Error sending client data: '.$this->dbconn->error);
77            $err_apps=false;
78            $err_exception=false;
79            if (count($apps) != 0){
80                if ($date == ''){
81                    $sql="insert into tmp_packages(client,app,value) values";
82                }else{
83                    $sql="insert into tmp_packages(client,app,value,date) values";
84                }
85                $values=array();
86                foreach ($apps as $app => $value){
87                    if (trim($app) == '' or trim($value) == ''){
88                        $err_apps=true;
89                        $err_exception=new Exception('Wrong application values');
90                        continue;
91                    }
92                    if ($date == ''){
93                        $values[]="($cli_id,'$app',$value)";
94                    }else{
95                        $values[]="($cli_id,'$app',$value,'$date')";
96                    }
97                }
98                if (count($values) > 0){
99                    $sql.=implode(',',$values);
100                    $done=false;
101                    $retry=1;
102                    while (! $done and $retry < 4){
103                        $res=$this->dbconn->query($sql);
104                        if ($res){
105                            $done=true;
106                        }else{
107                            $retry += 1;
108                            sleep($retry);
109                        }
110                    }
111                    if ($retry == 4 or ! $done){
112                        $err_apps=true;
113                        $err_exception=new Exception('Error sending client app data: '.$this->dbconn->error.' QUERY='.$sql);
114                    }
115                }
116            }
117            //End operations
118            $sql = "Update tmp_clients set status=1 where id = $cli_id and status=0";
119            $retry=1;
120            $done=false;
121            while (! $done and $retry < 4){
122                $res=$this->dbconn->query($sql);
123                if ($res){
124                    $done=true;
125                }else{
126                    $retry+=1;
127                    sleep($retry);
128                }
129            }
130            if ($retry == 4 or $cli_id == false){
131                throw new Exception('Error commiting client data: '.$this->dbconn->error);
132            }
133            if ($err_apps){
134                throw $err_exception;
135            }
136        }
137
138        private function load_alias(){
139                $sql="SELECT name,alias from Alias";
140                $result=$this->dbconn->query($sql);
141                while($row=$result->fetch_array(MYSQLI_ASSOC)){
142                        $this->alias[$row['name']]=$row['alias'];
143                }
144        }
145        function get_extended_data($app){
146            $today=date("Y-m-d");
147            $min_date=date("Y-m",strtotime($today." -1 year")).'-01';
148            $this->times=0;
149            // CLIENTS DISTRIBUTION PER RELEASE/FLAVOUR
150            $sql="select year(date) as year,month(date) as month,Releases_name,Flavours_name,count(*) as num_hosts from (select distinct Client_uid,date,Releases_name,Flavours_name from Client_Versions where date >= '$min_date' )t group by year,month,Releases_name,Flavours_name order by year Desc,month desc,Releases_name asc,num_hosts desc";
151            $stime=microtime(true);
152            $result=$this->dbconn->query($sql);
153            if ($result){
154                $this->times+=microtime(true)-$stime;
155                $clients_month=[];
156                $tmp=[];
157                while($row=$result->fetch_array(MYSQLI_ASSOC)){
158                    $date=$row['year'].'_'.$row['month'];
159                    $tmp[$date][$row['Releases_name']][$row['Flavours_name']]=intval($row['num_hosts']);
160                }
161                foreach ($tmp as $date){
162                    $clients_month[]=$date;
163                }
164            }else{
165                $clients_month=$this->dbconn->error;
166            }
167            // CLIENT UPDATES
168            $sql="select year,month,count(*) as nclients,sum(cnt)-count(*) as nclients_updated from (select Client_uid,count(Client_uid) as cnt,year(date) as year,month(date) as month from Client_Versions where date >= '$min_date' GROUP by Client_uid,year,month having count(Client_uid) >= 1 ) t group by year,month order by year desc,month desc";
169            $sql="select year,month,count(*) as nclients,sum(cnt)-count(*) as nclients_updated,Releases_name as rel,Flavours_name as fla from (select Client_uid,count(Client_uid) as cnt,year(date) as year,month(date) as month,Releases_name,Flavours_name from Client_Versions where date >= '$min_date' GROUP by Client_uid,year,month,Releases_name,Flavours_name having count(Client_uid) >= 1 ) t group by year,month,Releases_name,Flavours_name order by year desc,month desc";
170            $stime=microtime(true);
171            $result=$this->dbconn->query($sql);
172            if ($result){
173                $this->times+=microtime(true)-$stime;
174                $i=0;
175                $tmp=[];
176                while($row=$result->fetch_array(MYSQLI_ASSOC)){
177                    $date=$row['year'].'_'.$row['month'];
178                    $tmp[$date][$row['rel']][$row['fla']]=intval($row['nclients_updated']);
179                }
180                foreach($tmp as $date){
181                    $num_updates_month[]=$date;
182                }
183            }else{
184                $num_updates_month=$this->dbconn->error;
185            }
186            // CLIENT CHANGE RELEASE
187            $sql="select year,month,count(*) as upgrades_en_mes from (select year,month,Client_uid as cliente_upgradeado from (select Client_uid,year(date) as year,month(date) as month from Client_Versions where date >= '$min_date' GROUP by Client_uid,Releases_name,year,month)t group by month,year,Client_uid having(count(*))>1)t group by year,month order by year desc,month desc limit 12";
188            $stime=microtime(true);
189            $result=$this->dbconn->query($sql);
190            if ($result){
191                $this->times+=microtime(true)-$stime;
192                $change_releases=[0,0,0,0,0,0,0,0,0,0,0,0];
193                $i=0;
194                while($row=$result->fetch_array(MYSQLI_ASSOC)){
195                    $change_releases[$i++]=intval($row['upgrades_en_mes']);
196                }
197            }else{
198                $change_releases=$this->dbconn->error;
199            }
200            // CLIENT CHANGE FLAVOUR
201            $sql="select year,month,count(*) as cambio_sabor_en_mes from (select year,month,Client_uid as cliente_upgradeado from (select Client_uid,year(date) as year,month(date) as month from Client_Versions where date >= '$min_date' GROUP by Client_uid,Flavours_name,year,month)t group by month,year,Client_uid having(count(*))>1)t group by year,month order by year desc,month desc limit 12";
202            $stime=microtime(true);
203            $result=$this->dbconn->query($sql);
204            if ($result){
205                $this->times+=microtime(true)-$stime;
206                $i=0;
207                $change_flavour=[0,0,0,0,0,0,0,0,0,0,0,0];
208                while($row=$result->fetch_array(MYSQLI_ASSOC)){
209                    $change_flavour[$i++]=intval($row['cambio_sabor_en_mes']);
210                }
211            }else{
212                $change_flavour=$this->dbconn->error;
213            }
214           
215            //sanitize input
216            if ($app != NULL){
217                $app=preg_grep('/^[a-zA-Z0-9\-_]+$/',array($app));
218                if ($app != NULL and isset($app[0])){
219                    $app=$this->dbconn->real_escape_string($app[0]);
220                    $stats['apps']=[];
221                    $stats['apps']['app']=$app;
222                    $sql="select year(date) as year,month(date) as month,string,Releases_name as rel,Flavours_name as fla,sum(count) as count from RecvPackages where string='$app' and date >= '$min_date' group by year,month,Releases_name,Flavours_name order by year desc,month desc,sum(count) desc";
223                    $stime=microtime(true);
224                    $result=$this->dbconn->query($sql);
225                    if ($result){
226                        $this->times+=microtime(true)-$stime;
227                        $tmp=[];
228                        while($row=$result->fetch_array(MYSQLI_ASSOC)){
229                            $date=$row['year'].'_'.$row['month'];
230                            $tmp[$date][$row['rel']][$row['fla']]=intval($row['count']);
231                        }
232                        foreach($tmp as $date){
233                            $app_use[]=$date;
234                        }
235                        $stats['apps']['app_use']=$app_use;
236                    }else{
237                        $app_use=$this->dbconn->error;
238                    }
239                }
240            }
241            // FINALIZATION & WRITE STRUCTURE
242            if (isset($clients_month)){
243                $stats['clients']['clients_per_month']=$clients_month;
244            }
245            if (isset($num_updates_month)){
246                $stats['clients']['freq_updates_per_month']=$num_updates_month;
247            }
248            if (isset($change_releases)){
249                $stats['clients']['change_releases']=$change_releases;
250            }
251            if (isset($change_flavour)){
252                $stats['clients']['change_flavours']=$change_flavour;
253            }
254            $stats['debug_query_time']=strval(number_format($this->times,5));
255            if (file_exists($this->ka_file)){
256                    $stats['debug_keep_alive']=date('Y-m-d H:i',file_get_contents($this->ka_file));
257            }
258            return json_encode($stats);
259        }
260
261        function get_historic_data(){
262                $this->load_alias();
263                $obj=[];
264                $this->times=0;
265                foreach ($this->info_distro['distros'] as $distro){
266                        $dname=$distro['name'];
267                        $dlike=$distro['like'];
268                        $obj[$dname]=array();
269                        foreach ($distro['sabor'] as $sabor){
270                                $sname=$sabor['name'];
271                                $slike=$sabor['like'];
272                                $obj[$dname][$sname][]=$this->get_chart($dlike,$slike,'current');
273                                $obj[$dname][$sname][]=$this->get_chart($dlike,$slike,'old');
274                                $obj[$dname][$sname][]=$this->get_chart($dlike,$slike,'very_old');
275                        }
276                }
277                $obj['debug_query_time']=strval(number_format($this->times,3));
278               
279                if (file_exists($this->ka_file)){
280                    $obj['debug_keep_alive']=date('Y-m-d H:i',file_get_contents($this->ka_file));
281                }
282                return json_encode($obj);
283        }
284        function get_chart($version='',$sabor='',$type='current'){
285                if ($version != ''){
286                    $version = " and Releases_name = '$version' ";
287                }
288                if ($sabor != ''){
289                    $sabor = " and Flavours_name = '$sabor' ";
290                }
291                $order=" order by count desc limit 10 ";
292                $group=" group by app ";
293               
294                $where=$this->dates['date_'.$type]." $version $sabor ";
295                $where_clients=$this->dates['date_'.$type]." $version $sabor ";
296
297                $sql="SELECT string as app,sum(count) as count from RecvPackages where $where $group $order";
298                $sql_clients = "select count(distinct Client_uid) as count from Client_Versions where $where_clients $order";
299
300                return array($this->get_result_from_sql($sql),$this->get_clients_from_sql($sql_clients));
301        }
302        function get_clients_from_sql($sql){
303                $stime=microtime(true);
304                if ($result=$this->dbconn->query($sql)){
305                        $etime=microtime(true);
306                        $this->times+=($etime-$stime);
307                        while($row=$result->fetch_array(MYSQLI_ASSOC)){
308                                if (isset($row['count'])){
309                                        return array('nclients'=>$row['count']);
310                                }
311                        }
312                        return array('nclients'=>'not available');
313                }else{
314                        return array('nclients'=>$this->dbconn->error);
315                }
316               
317        }
318        function get_result_from_sql($sql){
319                $stime=microtime(true);
320                if ($result=$this->dbconn->query($sql)){
321                        $etime=microtime(true);
322                        $this->times+=($etime-$stime);
323                        $obj2=[];
324                        $nobj=0;
325                        while($row=$result->fetch_array(MYSQLI_ASSOC)){
326                                if (array_key_exists($row['app'],$this->alias)){
327                                        if (! empty($this->alias[$row['app']])){
328                                                if ($nobj < 10)
329                                                        $obj2[$this->alias[$row['app']]]=$row['count'];
330                                                $nobj++;
331                                        }
332                                }else{
333                                        if ($nobj < 10)
334                                                $obj2[$row['app']]=$row['count'];
335                                        $nobj++;
336                                }
337                        }
338                        return $obj2;
339                }else{
340                    return $this->dbconn->error;
341                }
342        }
343
344} 
345
346?>
Note: See TracBrowser for help on using the repository browser.