Autor Téma: Služba - logování vyjímek  (Přečteno 12858 krát)

Offline hlucheucho

  • Plnoletý
  • ***
  • Příspěvků: 196
  • Karma: 2
Služba - logování vyjímek
« kdy: 02-09-2014, 16:29:30 »
Ahoj,

chtěl jsem si logovat vyjímky které vznikají při běhu služby kvůli diagnostice.
Kód: [Vybrat]
void __fastcall TJadro308::ServiceCreate(TObject *Sender)
{
Forms::Application->OnException = LogVyjimky;
}

void __fastcall TJadro308::LogVyjimky(TObject *Sender, Exception *E)
{
FILE *fw;
SYSTEMTIME lt;

fw = _wfopen(ChangeFileExt(Forms::Application->ExeName, ".log").w_str(), L"a");
if (fw != NULL) {
   GetLocalTime(&lt);
   fwprintf(fw, L"%d-%02d-%02d %d:%d:%d %s\r\n", lt.wYear, lt.wMonth, lt.wDay,
lt.wHour, lt.wMinute, lt.wSecond, E->Message.w_str());
   fclose(fw);
}
Forms::Application->Terminate();
}

Když dojde k vyjímce, žádný soubor se nevytvoří. zkoušel jsem vytvoření a zápis do souboru při obsluze událostí OnCreate a OnStart, zde práce se souborem fungovala. Stejně tak je výše uvedený kód funkční v běžné "oknové" aplikaci.  Metoda LogVyjímky je private.  C++ Builder XE5, Win 7.

hu

Offline Radek Červinka

  • Administrátoři
  • Padawan
  • *****
  • Příspěvků: 3532
  • Karma: 112
    • Verze Delphi: D2007, DXE + 2 poslední
    • O Delphi v češtině
Re:Služba - logování vyjímek
« Odpověď #1 kdy: 02-09-2014, 16:46:32 »
Zkus misto Forms::Application->ExeName pouzit ParamStr(0)
Embarcadero MVP - Czech republic

Offline hlucheucho

  • Plnoletý
  • ***
  • Příspěvků: 196
  • Karma: 2
Re:Služba - logování vyjímek
« Odpověď #2 kdy: 03-09-2014, 10:55:12 »
Nepomohlo. Dále jsem vyzkoušel metodu LogVyjimky mít Public a instalovat službu z adresáře Program files také bez výsledku  :( Nechápu, proč se v tomto služba chová jinak než aplikace.

hu

Offline pf1957

  • Padawan
  • ******
  • Příspěvků: 3530
  • Karma: 139
    • Verze Delphi: D2007, XE3, DX10
Re:Služba - logování vyjímek
« Odpověď #3 kdy: 03-09-2014, 11:38:19 »
Nepomohlo. Dále jsem vyzkoušel metodu LogVyjimky mít Public a instalovat službu z adresáře Program files také bez výsledku  :( Nechápu, proč se v tomto služba chová jinak než aplikace.
1) K pochopeni rozdilu si vytvor nekde na piskovisti prazdnovou novou sluzbu a prazdnou VCL aplikaci: uvidis, ze sluzba zadne Forms a tim i Forms.TApplication nepouziva a ani by nemela - vizualni prvky ve sluzbe nemaji co delat... Sluzba pouziva SvcMgr.TServiceApplication s instanci tamtez a dopln si znalosti

2) Dalsi rozdil je, pod jakym uctem ma byt sluzba spoustena a z toho plynouci prava treba do adresare

3) Na Windows se do Program Files nepise, takze si to logovani nejdriv odlad treba v C:\Temp\muj.log a az ti to bude fungovat, tak res, jak prebrat jmeno sluzby (GetModuleName) apod.




Offline Radek Červinka

  • Administrátoři
  • Padawan
  • *****
  • Příspěvků: 3532
  • Karma: 112
    • Verze Delphi: D2007, DXE + 2 poslední
    • O Delphi v češtině
Re:Služba - logování vyjímek
« Odpověď #4 kdy: 03-09-2014, 12:44:51 »
Nepomohlo. Dále jsem vyzkoušel metodu LogVyjimky mít Public a instalovat službu z adresáře Program files také bez výsledku  :( Nechápu, proč se v tomto služba chová jinak než aplikace.

hu

a jen tak pro zajimavost co ti vrati ParamStr(0)?
Embarcadero MVP - Czech republic

Offline hlucheucho

  • Plnoletý
  • ***
  • Příspěvků: 196
  • Karma: 2
Re:Služba - logování vyjímek
« Odpověď #5 kdy: 03-09-2014, 14:54:45 »
ParamStr(0) vrátí Full Path exe souboru služby.

Možná jste to přehlédli, ale když zkusím zapsat do souboru při obsluze událostí OnCreate a OnStart služby, kotevření souboru a zápisu dojde. Proto bych vyloučil práva k adresáři a problém se jménem souboru. Koneckonců zápis do C:\test se chová úplně stejně. Zřejmě je používán defaultní handler vyjímek nikoliv můj.

hu

Offline pf1957

  • Padawan
  • ******
  • Příspěvků: 3530
  • Karma: 139
    • Verze Delphi: D2007, XE3, DX10
Re:Služba - logování vyjímek
« Odpověď #6 kdy: 03-09-2014, 15:10:45 »
Zřejmě je používán defaultní handler vyjímek nikoliv můj.
A dival ses, jak vypada TServiceApplication?

Ta sama odchytava neosetrene vyjimky a pise je do systemoveho logu, takze zrus to prirazeni OnException a vyvolej vyjimku -> mela by se ti objevit v systemovem logu. A pokud chces jine chovani, budes si muset subclasnout TServiceApplication, prekryt DoHandleException, zrusit puvodni instanci TServiceApplication a nahradit ji instanci subclasnute tridy.

Offline hlucheucho

  • Plnoletý
  • ***
  • Příspěvků: 196
  • Karma: 2
Re:Služba - logování vyjímek
« Odpověď #7 kdy: 03-09-2014, 16:14:03 »
Podstata věci: službě nelze takto snadno "podstrčit" globální handler vyjímek?

hu

Offline pepak

  • Padawan
  • ******
  • Příspěvků: 1574
  • Karma: 37
    • Pepak.net
Re:Služba - logování vyjímek
« Odpověď #8 kdy: 03-09-2014, 20:01:42 »
Službě nelze snadno podstrčit spoustu věcí, tak proč ne i exception handler?

Offline pf1957

  • Padawan
  • ******
  • Příspěvků: 3530
  • Karma: 139
    • Verze Delphi: D2007, XE3, DX10
Re:Služba - logování vyjímek
« Odpověď #9 kdy: 03-09-2014, 20:37:21 »
Podstata věci: službě nelze takto snadno "podstrčit" globální handler vyjímek?
Cistym zpusobem ne (proc taky, kdyz sama loguje tam, kam se maji mimoradne udalosti logovat. A neobslouzena vyjimka je mimoradnou udalosti).

Necistym zpusobem by to za urcitych prepodkladu  melo jit udelat tak, ze se najde vhodne misto (asi na zacatku OnExecute 1. instance TService) a tam se prepise handler Forms.Application.OnException.

Offline hlucheucho

  • Plnoletý
  • ***
  • Příspěvků: 196
  • Karma: 2
Re:Služba - logování vyjímek
« Odpověď #10 kdy: 03-09-2014, 22:45:34 »
Vlastní log by měl výhody - možnost informovat o události s minimálním časovým odstupem (sms) a možnost logovat podrobnosti např. obsah (některých) proměnných. Prostě tyto možnosti mít nebudu.

hu

Offline pf1957

  • Padawan
  • ******
  • Příspěvků: 3530
  • Karma: 139
    • Verze Delphi: D2007, XE3, DX10
Re:Služba - logování vyjímek
« Odpověď #11 kdy: 04-09-2014, 08:05:10 »
Vlastní log by měl výhody - možnost informovat o události s minimálním časovým odstupem (sms) a možnost logovat podrobnosti např. obsah (některých) proměnných. Prostě tyto možnosti mít nebudu.
Jenomze tohle je "navrch huj a uvnitr fuj"  >:(

Jeste jednou: ve slusne napsanem programu nemuze vzniknout neosetrena vyjimka a osetrit vyjimku i s celymi cirkusem co popisujes neni zadny problem, jen se to nedela pres centralni handler neosetrenych vyjimek - na ten to v desktop aplikacich nechavaji jen strikaci, ale ti se zatim (zaplatpanbu) do sluzeb spis nepousteli  ;-)

A zapis do systemoveho logu slouzi administratorovi, aby vedel, ze mu na stroji bezi nejaka zprasena aplikace a aby ji odinstaloval ASAP :-)
« Poslední změna: 04-09-2014, 08:13:40 od pf1957 »

Offline hlucheucho

  • Plnoletý
  • ***
  • Příspěvků: 196
  • Karma: 2
Re:Služba - logování vyjímek
« Odpověď #12 kdy: 04-09-2014, 10:02:17 »
Na rozdíl od administrátora potřebuji vědět, proč služba spadla. V situaci, kdy tonoucí se stébla chytá, je každá informace navíc cenná. "Berlička" abych se "dobelhal" k místu kde jsem udělal chybu. V odladěné službě je to nadbytečná věc. Pomůcka pro urychlení ladění a testování služby.

hu

Offline pf1957

  • Padawan
  • ******
  • Příspěvků: 3530
  • Karma: 139
    • Verze Delphi: D2007, XE3, DX10
Re:Služba - logování vyjímek
« Odpověď #13 kdy: 04-09-2014, 10:41:51 »
Na rozdíl od administrátora potřebuji vědět, proč služba spadla. V situaci, kdy tonoucí se stébla chytá, je každá informace navíc cenná. "Berlička" abych se "dobelhal" k místu kde jsem udělal chybu. V odladěné službě je to nadbytečná věc. Pomůcka pro urychlení ladění a testování služby.
Kazda slusne napsana sluzba/aplikace produkuje log, vetsinou z konfigurovatelnym stupnem detailnosti - dnes se to k tomu napric platformami pouziva log4j resp. log4net resp. log4delphi (s tim nemam zkusenosti, protoze na platforme Delphi jsme si pred mnoha lety napsali vyspelejsi logovani). Je totiz naivni si myslet, ze pri ladeni najdes vsechny chyby a ze se ti zadna exception nemuze vyskytnout i v radnem provozu, at uz z jakychkoli pricin, zejmena u sluzby, ktera muze bezet non-stop cele mesice bez restartu stroje.

Ale to se  vsechno resi osetrenymi vyjimkami, protoze u softu, ktery neco prepretrzite dela, je pri hledani problemu nutne znat kontext co delal, takze je to treba logovat v miste, kde jsou takove informace k dispozici (napr. info ze stack trace, ze to spadlo v procedure, ktera se vola treba 10 x za vterinu, je v podstate k nicemu).

Nechat propadnout neosetrenou vyjimku je hrubka.