UNIVERZA V MARIBORU FAKULTETA ZA ELEKTROTEHNIKO, RAČUNALNIŠTVO IN INFORMATIKO VISOKOŠOLSKI STROKOVNI ŠTUDIJ Informatika in tehnologije komuniciranja POROČILO PRAKTIČNEGA IZOBRAŽEVANJA v Amis d.o.o., Maribor Čas opravljanja od 17.3. 2014 do 17.5. 2014 Mentor v GD Matej Golob mag. posl. inf. Študent Janja Kolarič Vpisna številka E1053382 E-pošta janja.kolaric1@gmail.com Telefon 031 750278
KAZALO VSEBINE 1 Uvod... 5 2 Gospodarska družba... 5 2.1 Ponudba podjetja... 5 3 Praktično izobraževanje... 6 3.1 Uporabljeno orodje... 6 3.1.1 Microsoft SQL Server 2012... 6 3.2 Uporabljene storitve... 6 3.2.1 SSIS... 6 3.2.2 SSAS... 6 4 Projekt... 7 4.1 Parsanje Apache.log datotek... 7 4.2 Opis komponent v ETL procesu:... 7 4.3 Lokalna baza v SQL Server Management Studio... 10 4.4 SSAS projekt... 12 5 Priloga... 20 6 Sklep... 23 KAZALO SLIK Slika 1: Logotip podjetja Amis d.o.o.... 5 Slika 2: Connection Manager... 7 Slika 3: Package Control Flow... 7 Slika 4: Package Data Flow... 8 Slika 5: Vsebina lokalne baze 1... 9 Slika 6: Vsebina lokalne baze 2... 9 Slika 7: Lokalna baza MobiaTV1... 10 Slika 8: Named Calculation... 12 Slika 9: Zgradba SSAS projekta... 13 Slika 10: SSAS Data Source View... 13 Slika 11: OLAP kocka... 14 Slika 12: Fact Table/ Tabela dejstev... 14 Slika 13: Združitev tabel za EPG... 16 Slika 14: Povpraševanje za tabelo dejstev... 17 Slika 15: Excel povezava... 18 Slika 16: Povezava med zbirko podatkov in tabelo... 18 Slika 17: Dokončanje povezave med podatki in kocko... 19 Slika 18: Pregled podatkov v excel datoteki... 19 2
3
4
1 Uvod Praktično izobraževanje sem opravljala v podjetju AMIS d.o.o. v Mariboru na sektorju za informacijsko tehnologijo. AMIS d.o.o. je telekomunikacijsko podjetje, ki ponuja internet, televizijo in telefonijo. V obdobju dveh mesecev sem pridobila veliko znanja s področja podatkovnega skladiščenja in upravljanja z bazo podatkov. Podrobneje sem spoznala delo z orodjem SQL server 2012 ter storitvami (SSIS, SSAS in SSRS). 2 Gospodarska družba Podjetje AMIS d.o.o. je nastalo leta 1995 kot ponudnik interneta, televizije in telefonije telekomunikacijskega podjetja Medinet d.o.o., ki zagotavlja 98% pokritost Slovenije s širokopasovnimi storitvami. Leta 1997 je podjetje Amis d.o.o. postalo lastnik in upravljavec omrežja, kot tudi zaščitena blagovna znamka. Skupina Amis zaposluje več kot 150 zaposlenih. Slika 1: Logotip podjetja Amis d.o.o. 2.1 Ponudba podjetja Podjetje ponuja pakete preko ADSL omrežja (paketi): Paket trojka Paket dvojka TV Paket dvojka Tel Paket enka in optike (samostojne storitve, paketi): Optika paket trojka Optika paket dvojka Samostojna storitev internet Samostojna storitev telefonija Samostojna storitev televizija 5
3 Praktično izobraževanje Prvi teden praktičnega izobraževanja je bil namenjen spoznavanju podjetja, vzpovstavitvi delovnega okolja ter spoznavanju orodja za skladiščenje podatkov. Spoznala sem delo z SQL Server Management Studiom, delo s storitvami, kot so SSIS (SQL Server Integration Services), SSAS (SQL Server Analysis Services) in SSRS (SQL Server Reporting Services). Dotično delo se navezuje na internetno televizijo MobiaTV, kjer bom iz MobiaTV.log datotek pridobila podatke za obdelavo in uporabo. 3.1 Uporabljeno orodje 3.1.1 Microsoft SQL Server 2012 Microsoft SQL Server je sistem za upravljanje z bazami podatkov, ki ga je razvil Microsoft. Glavna naloga je shranjevanje in pridobivanje podatkov. Obstaja pet različic Microsoft SQL Server, namenjene različnim, majhnih aplikacij do velikih aplikacij. Njegova primarna poizvedbena jezika sta T-SQL in ANSI SQL. 3.2 Uporabljene storitve 3.2.1 SSIS SQL Server Integration Services (SSIS) je del programske opreme Microsoft SQL Server 2012. SSIS je platforma za integracijo podatkov in aplikacij. Uporablja se za pridobivanje podatkov, preoblikovanje in polnjenje (ETL) ter za vzdrževanje podatkovnih baz in večdimenzionalnih podatkov kocke. ETL proces zavzema največji procent dela za pridobivanje podatkov. 3.2.2 SSAS SQL Server Analysis Services (SSAS) je za analitično obdelavo OLAP (Online Analytical Processing) rešitev. Rešitve OLAP so osrednjega pomena za poslovno inteligenco. Z razumljivimi podatki lažje poslujemo in sprejemamo odločitve. SSAS uporabnikom omogoča, da združimo podatke iz več relacijskih podatkovnih baz v izbrano lokacijo in nato podatke predstavimo, za uporabnike najbolj preprost način. 6
Zraven svoje funkcionalnosti OLAP, Analysis Services omogoča tabelarni model v pomnilniku, ki je namenjen za hitro izdelavo prototipov in zelo hitre poizvedbe. 4 Projekt To poglavje bo vsebovalo opis dela po poglavjih. Ta poglavja so: pretvorba Apache.log datotek, izdelava SSIS projekta, izdelava lokalne baze, izdelava SSAS projekta ter OLAP kocke in oblikovanje podatkov v excel datoteki. 4.1 Parsanje Apache.log datotek Po instalaciji Microsoft SQL Server 2012, sem ustvarila SSIS projekt»package.dtsx«kamor sem vključila ETL postopek, ki pretvori podatke ter jih vstavil v lokalno bazo ustvarjeno v SQL Server Management Studio. Razdeljen je na več sekcij, najbolj pomembni pa sta Control Flow in Data Flow. Za povezavo z lokalno bazo MobiaTV1 potrebujemo (Connection Manager). Slika 2: Connection Manager 4.2 Opis komponent v ETL procesu: Slika 3: Package Control Flow Komponenta»Execute SQL Task«v Control Flow, imenovana»brisanje baze, če vsebuje podatke«, vsebuje naslednji SQL stavek:»if(exists (select * from MobiaTV1)) delete from dbo.mobiatv1;«. 7
Komponenta»Data Flow Task«v Control Flow, imenovana»parsanje log datotek«, kaže na zaporedno izvajanje paketa v sekciji»data Flow«. Slika 4: Package Data Flow Prva komponenta»script Component«vsebuje C# kodo, ki nam»parsa«(pretvori) zapise iz.log datotek (LIVE in TIMESHIFT podatki) po različnih členih. [V prilogi.] Primer dveh različnih zapisov v Apache.log datoteki: 1. LIVE PODATEK "XX.XX.XX.XXX»-«- [09/Apr/2014:07:35:20 +0200] ""GET /ts/popoto/stream_wifi_1200k.m3u8 HTTP/1.1"" 200 400 ""-"" ""VRPC"" 5.001 ""CC: SVN"" ""CN: Slovenia""" 2. TIMESHIFT PODATEK "XX.XX.XXX.XX»» - [09/Apr/2014:07:35:44 +0200] ""GET /ts/natgeo/2014-04-06/1210211/natgeo_wifi_1200k-6217.ts HTTP/1.1"" 200 1839580 ""-"" ""AppleCoreMedia/1.0.0.11A465 (ipad; U; CPU OS 7_0 like Mac OS X; en_us)"" 1.331 ""CC: SVN"" ""CN: Slovenia""" Komponenta Derived Column, imenovano Split DateTime, izvede transformacijo datum-časa (razdeli datum-čas na dva dela, datum in čas); [2014-04-09 07:35:20.000] 1. Datum, expression: (DT_DBDATE)(datum_cas), Datatype: database date [DT_DBDATE]; [2014-04-09] 2. Cas, expression: (DT_DBTIME)(datum_cas), DataType: database time [DT_DBTIME]; [07:35:20.000] 8
Komponenta Flat File Destination, imenova»error Destination«je zgolj za evidenco, kateri podatki so šli kot»error«podatki mimo lokalne baze. Ko se SSIS paket uspešno izvede se podatki zapišejo v lokalno bazo v»sql Server Management Studio«. SQL poizvedba: select * from MobiaTV.dbo.MobiaTV1; Slika 5: Vsebina lokalne baze 1 Slika 6: Vsebina lokalne baze 2 9
4.3 Lokalna baza v SQL Server Management Studio Slika 7: Lokalna baza MobiaTV1 Atribut»cas_koncni«se vnese s proceduro, ki se izvede po zapisu vseh podatkov v lokalno bazo.»cas_koncni«se zapiše v bazo kot začetni čas prejšnjega zapisa pod istim atributom (ipnaslovom). [Programmability-Stored Procedures-New Stored Procedure]. USE [MobiaTV] GO /****** Object: StoredProcedure [dbo].[doloci_koncni_cas] Script Date: 19.5.2014 11:53: 28 ******/ SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO -- ============================================= -- Author: <Kolarič Janja> -- Create date: <7.5.2014> -- Description: <Update cas_koncni- določitev koncnega casa gledanja> -- ============================================= 10
ALTER PROCEDURE [dbo].[doloci_koncni_cas] AS BEGIN -- SET NOCOUNT ON added to prevent extra result sets from -- interfering with SELECT statements. SET NOCOUNT ON; -- deklariram kurzor v katerega dam vse vrstice ki majo cas_koncni null declare kurzor cursor for select ipnaslov, datum_cas from dbo.mobiatv1 where cas_koncni i s null -- odprem kurzor open kurzor -- deklariram spremenljivki v kateri bom iz kurzorja iz vsake vrstice dala noter ip in datum_cas declare @ip varchar(200) declare @datum_cas datetime -- potegni vrstico iz kurzorja fetch next from kurzor into @ip, @datum_cas -- ponavljaj dokler kurzor vrne veljaven podatek while @@FETCH_STATUS=0 begin -- updejtaj cas_koncni iz prejsnjega zapisa update dbo.mobiatv1 set cas_koncni = @datum_cas where ipnaslov = @ip and datu m_cas = (select max(datum_cas) from dbo.mobiatv1 where ipnaslov=@ip and datum_cas < @datum_cas); -- izpiši števila vrstic ki so bila updejtana print @@rowcount -- potegni vrstice iz kurzorja fetch next from kurzor into @ip, @datum_cas end END Drugi način zapisa»cas_koncni«je možen s»triggerjem«, ki se izvede za vsakim trenutnim zapisom podatka v bazo. [Table-Triggers-New Trigger] USE [MobiaTV] GO /****** Object: Trigger [dbo].[updatevsakevrstice] Script Date: 19.5.2014 12:00:57 *** ***/ SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO -- ============================================= 11
-- Author: <Kolaric Janja> -- Create date: <7.5.2014> -- Description: <Update vsake vrstice in vpis koncnega casa v stolpec cas_koncni> -- ============================================= ALTER TRIGGER [dbo].[updatevsakevrstice] ON [dbo].[mobiatv1] AFTER INSERT AS BEGIN update dbo.mobiatv1 set cas_koncni = (select datum_cas from inserted) where ipnaslov = (s elect ipnaslov from inserted) and datum_cas = (select MAX(datum_cas) from dbo.mobiatv 1 where ipnaslov = (select ipnaslov from inserted) and datum_cas!= (select datum_cas from inserted)); END Atribut v tabeli dbo.mobiatv1»dolzina_gledanja«se ne izračuna takoj ko so podatki vpisani v bazo. Izračunamo ga takrat, ko kreiramo SSAS projekt in»view«za tabelo dejstev. Potrebujemo DataSource, ki je povezava na lokalno bazo»datasources- Mobia TV.ds«. 4.4 SSAS projekt V SQL Server Data Tools ustvarimo nov projekt kjer definiramo»data Source«, povezavo do lokalne baze v SQL Server Managemenst Studio. Kreiramo»Data Source View«, kjer zajamemo tabele iz lokalne baze. Na kreiranem pogledu si po lastnih potrebah ustvarimo»new Named Calculation«, ki nam smiselno predstavijo podatke. Slika 8: Named Calculation 12
Slika 9: Zgradba SSAS projekta Slika 10: SSAS Data Source View 13
Slika 11: OLAP kocka Z desnim klikom na katerokoli izmed tabel v kocki ali na pogledu (Explore Data) imamo pregled nad zapisi, ki smo jih vnesli v bazo. Slika 12: Fact Table/ Tabela dejstev 14
Iz tabele dejstev prikazuje enega uporabnika pod enim IP naslovom, ki je gledal en kanal, na tem kanalu pa je gledal dve različni oddaji (dva različna EpgID-ja). Da smo povezali uporabnika z EPG (Electronic Program Guide), smo morali narediti povezavo med tabelami pridobljenega EPG-ja (Epg, Genres in ChannelVersions). V SQL Server Management Studio naredimo»view«s SQL povpraševanjem. SQL povpraševanje: SELECT dbo.epg.epgid, dbo.epg.titleslo, dbo.epg.endtime, dbo.epg.starttime, db o.genres.genrenameslo, REPLACE(dbo.ChannelVersions.ChannelName, ' ', '') as Channel Name, dbo.epg.channelversionid FROM dbo.epg INNER JOIN dbo.genres ON dbo.epg.genreid = dbo.genres.genreid INNER JOIN dbo.channelversions ON dbo.epg.channelversionid = dbo.channelversions.cha nnelversionid 15
Slika 13: Združitev tabel za EPG 16
SQL povpraševanje Fact Table oz. tabelo dejstev za en IP naslov: SELECT l.id AS MobiaTVid, dbo.oddaja.epgid, dbo.datum_cas.iddatumcas, l.cas_kon cni - l.datum_cas AS dolzina_gledanja, dbo.uporabnik.iduporabnik, dbo.tslive.idtslive, dbo.kanal.idkanal, dbo.status_code.idstatuscode, dbo.drzava.iddrzava FROM dbo.mobiatv1 AS l INNER JOIN dbo.oddaja ON l.kanal = dbo.oddaja.channelname INNER JOIN dbo.status_code ON l.id = dbo.status_code.idstatuscode INNER JOIN dbo.drzava ON l.id = dbo.drzava.iddrzava INNER JOIN dbo.kanal ON l.id = dbo.kanal.idkanal AND dbo.oddaja.channelname = dbo.kanal.kanal INNER JOIN dbo.tslive ON l.id = dbo.tslive.idtslive INNER JOIN dbo.datum_cas ON l.id = dbo.datum_cas.iddatumcas INNER JOIN dbo.uporabnik ON l.id = dbo.uporabnik.iduporabnik WHERE (l.datum_cas > dbo.oddaja.starttime) AND (l.cas_koncni < dbo.odda ja.endtime) AND (l.ipnaslov = 'xx.xx.xx.xx') OR (l.datum_cas < dbo.oddaja.starttime) AND (l.cas_koncni > dbo.oddaja.endtime) AND (l.ipnaslov = 'xx.xx.xx.xx') OR (l.datum_cas BETWEEN dbo.oddaja.starttime AND dbo.oddaja.endtime) AND ( l.ipnaslov = 'xx.xx.xx.xx') OR (l.cas_koncni BETWEEN dbo.oddaja.starttime AND dbo.oddaja.endtime) AND ( l.ipnaslov = 'xx.xx.xx.xx') Slika 14: Povpraševanje za tabelo dejstev 17
Končni del povezava OLAP kocke oz. SSAS projekta s excel datoteko. V excel datoteki naredimo povezavo med SSAS projektom in trenuntim excelom. [Podatki-Iz drugih virov-iz analitičnih storitev-ustvarimo povezavo] Slika 15: Excel povezava Slika 16: Povezava med zbirko podatkov in tabelo 18
Slika 17: Dokončanje povezave med podatki in kocko Ko dokončamo povezavo med kocko in podatki se nam ustvari vrtilna tabela, kjer lahko označujemo polja, s tem pa dobimo vizualni prikaz podatkov. Tako pridobivanje podatkov je enostavnejše in hitrejše. Slika 18: Pregled podatkov v excel datoteki 19
5 Priloga public override void CreateNewOutputRows() string[] filepaths = Directory.GetFiles(@"C:\Users\janjak\Desktop\Logi"); foreach (string file in filepaths) StreamReader sr = new StreamReader(file); string line = ""; CultureInfo ci = CultureInfo.CreateSpecificCulture("en-US"); // beri datoteko od začetka do konca while ((line = sr.readline())!= null) try if (line.indexof("get") == -1) continue; //brisanje prvega in zadnjega narekovaja v stringu line = line.trimstart('"').trimend('"'); // branje IP naslova string ip = line.substring(0, line.indexof(' ')); line = line.substring(line.indexof(' ') + 1); // branje domene string domena = line.substring(0, line.indexof(' ')); line = line.substring(line.indexof(' ') + 1); // branje celega datuma [DateTime] string celi_datum = line.substring(line.indexof('[') + 1, line.indexof(']') - line.indexof('[') - 1); line = line.substring(line.indexof(']') + 1); //branje datuma string datum = celi_datum.substring(0, celi_datum.indexof(" ")); // branje časovnega pasa string casovni_pas = celi_datum.substring(celi_datum.indexof(" ") + 1); //notri je "GET... //odstrani prvi narekovaj, ker je samo v napoti line = line.substring(line.indexof("\"get")); int prvi_narekovaj = line.indexof("\""); int drugi_narekovaj = line.indexof("\"", prvi_narekovaj + 1); //pridobitev celega niza med prvim in naslednjim narekovajem string celi_niz = line.substring(prvi_narekovaj + 1, drugi_narekovaj - 1); 20
if (celi_niz == "") Console.WriteLine("Napaka v branju! Ni vsebine!"); return; //v line shrani vse za drugim narekovajem line = line.substring(drugi_narekovaj + 2); // presledki spredaj in odzadaj so odstranjeni line = line.trim(); //sedaj je noter v line: 200 400 "-" "VRPC"... //branje status code string statuscode = line.substring(0, line.indexof(' ')); line = line.substring(line.indexof(' ') + 1); // če je statuscode drugačna od 200, potem gre ponovno od začetka //if (statuscode!= "200") // continue; //splitanje niza po presledkih, [' '] string[] array_celi_get = celi_niz.split(' '); if (array_celi_get[1].indexof("/im/") > 0 array_celi_get[1].indexof("/iview/") > 0 array_celi_get[1].indexof("/amisapps/") > 0) continue; //dodaj novo vrstico this.output0buffer.addrow(); // izpis podatkov v mojo bazo (v primeru da statuscode!= 200, da ne bo nepotrebnih/nepopolnih podatkov metalo v bazo) Output0Buffer.ipNaslov = ip; Output0Buffer.naslov = domena; Output0Buffer.datumcas = DateTime.ParseExact(datum,"dd/MMM/yyyy:HH:m m:ss", ci); Output0Buffer.caspas = casovni_pas; Output0Buffer.statusCode = statuscode; char[] charseparator = new char[] '/' ; //splitanje niza po ['/'] string[] get_request = array_celi_get[1].split(charseparator, emoveemptyentries); StringSplitOptions.R if (get_request.length >= 3) try DateTime.ParseExact(get_request[2], "yyyy-dd-mm", ci); // Je TIMESHIFT if (get_request.length > 4) 21
; get_request[2] = get_request[2] + "/" + get_request[3] + "/" + get_request[4] Output0Buffer.TimeShift = get_request[2]; Output0Buffer.direktorij = get_request[0]; Output0Buffer.kanal = get_request[1]; else get_request[2] = get_request[2] + "/" + get_request[3]; Output0Buffer.TimeShift = get_request[2]; Output0Buffer.direktorij = get_request[0]; Output0Buffer.kanal = get_request[1]; catch (Exception e) //Je LiveTV livetv(get_request, ref Output0Buffer); else //Je LiveTV livetv(get_request, ref Output0Buffer); //branje GET zahteve string getorset = array_celi_get[0]; Output0Buffer.zahteva = getorset; //sedaj je noter v line: 400 "-" "VRPC"... //branje prenesenih podatkov string preneseni_podatki = line.substring(0, line.indexof(' ')); line = line.substring(line.indexof(' ') + 1); Output0Buffer.prenospodatkov = preneseni_podatki; //sedaj je noter v line: "-" "VRPC"... line = line.substring(line.indexof(' ') + 1); line = line.trimstart('"').trimend('"'); string up_dostop = line.substring(0, line.indexof('"')); Output0Buffer.updostop = up_dostop; //branje zadnjega dela stringa v "line" string drzava = line.substring(line.indexof("cn:") + 3); drzava = drzava.substring(0, drzava.length); drzava = drzava.trim(); Output0Buffer.drzava = drzava; catch (Exception ex) MessageBox.Show("Napaka v pisanju podatkov" + ' ' + ex.tostring()); 22
public static void livetv(string[] get_request, ref Output0Buffer buffer) // Je LIVETV if (get_request.length == 0) buffer.livetv = "/"; buffer.direktorij = "/"; buffer.kanal = "/"; else if (get_request.length == 1) buffer.livetv = get_request[0]; buffer.direktorij = "/"; buffer.kanal = "/"; else if (get_request.length == 2) buffer.livetv = get_request[1]; buffer.direktorij = get_request[0]; buffer.kanal = "/"; else if (get_request.length == 3) get_request[2] = get_request[1] + get_request[2]; buffer.livetv = get_request[2]; buffer.direktorij = get_request[0]; buffer.kanal = get_request[1]; 6 Sklep Praktično izobraževanje je zame bilo zelo uspešno, saj sem v tem obdobju pridobila zelo veliko uporabnega znanja s področja podatkovnega skladiščenja. Spoznala sem tudi delovanje samega podjetja, njegovih funkcionalnosti in zadolžitev. 23