monitorování změn v adresářové struktuře rubrika: Programování: .Net

5 dzejkob
položil/-a 12.6.2013

Potřeboval bych vyřešit následující problém:

  • aplikace, která bude sledovat změny ve specifické adresářové podstruktuře (vytvoření, smazání, přejmenování, přesun)
  • měla by sledovat i přístup, tedy otevření souboru, aktualizace souboru
  • změny se budou posílat na http rozhraní
  • musí být ošetřeny stavy, kdy nebude spuštěná aplikace, výpadek spojení nebo jiné selhání monitoringu (aplikace tedy musí umět poslat kompletní otisk struktury)
  • je klíčové, aby změny byly vidět v reálném čase

Jediné řešení, které mě napadlo, je oprášit .NET a pomocí FileSystemWatcher zachytávat změny. Problémy jsou přesuny adresářů. Dále si aplikace na straně http rozhraní musí ukládat svůj kompletní stav struktury a ten porovnávat s novým stavem - porovnáním dvou stromů - je to nezbytné právě kvůli možným výpadkům.

Implementovat to řešení na straně http rozhraní nelze - stroje nejsou na stejných místech a i kdyby, tak je to windows x linux a zachytávat změny na sambě asi též nereálné.

Napadá vás nějaké elegantnější hotové řešení?

Komentáře

  • Anonym : Jaký konkrétní problém chcete řešit? 12.6.2013
  • dzejkob : Je to "jednoduše" požadavek - několik zaměstnanců pracuje nad "bincem" ve fs na windows serveru, tento binec je nějak logicky organizován (struktura adresářů) a ten je/může být napárován na specifické entity v informačním systému (který není na lokální síti) a může nějak modifikovat stav těchto entit. Je to možná trochu šílené ale naučit zaměstnance aby pracovali s IS nějak přímo v podstatě nelze. 12.6.2013
  • Petr Voneš : Nelze v podstate jen zakazat pristup (pravy) k FS a donutit je pracovat s nejakou vyssi aplikaci ? Jine reseni nikam nevede. 12.6.2013
  • dzejkob : To je trochu problém - IS je na odděleném stroji jako webová aplikace, kde je navíc relativně drahý úložný prostor a těch dat bude hodně. A cpát to tam přes nějaký webform (nebo i nějaký lepší mechanismus) je režie navíc - netřeba zmiňovat, že tahání zpět by bylo taktéž problematické a ty data jsou účelná i bez IS - informace v systému jsou podpůrné, nikoliv bezprostředně nezbytné. Není problém donutit uživatele, aby dodržovali nějaké konvence. Nad tím vším bude supervisor, který s IS pracovat umí a bude to celé usměrňovat - nutno dodat, že to nebude zdaleka jediná funkce toho člověka v rámci spolupráce s těmi lidmi. 12.6.2013
  • dzejkob : Ještě vidím jeden problém - zda se dá záznamu v NTFS (složce / souboru) zjistit nějaké UID, aby šlo podchytit změny názvů? 12.6.2013
  • Petr Voneš : Slo by pouzit NTFS OBJECT ID http://blogs.technet.com/b/askcore/archive/2010/08/25/ntfs-file-attribut... ale zase je treba to mit trochu pod kontrolou. Nejsnazsi by bylo mit ten identifikator primo v souboru. Uvedeny problem (pridani metadat do file systemu) melo resit WinFS, ovsem Microsoft to stopnul. 12.6.2013
  • dzejkob : No je potřeba, aby to ID bylo pevné do smazání souboru - tedy pokud někdo udělá rename, nebo se provede nějaká systémová akce na disku (třeba defragmentace) tak aby ID zústalo stejné - metadata se na to už nabalí snadno. Děkuji, vyzkouším 12.6.2013
odkaz
9 Petr Voneš
odpověděl/-a 12.6.2013

Toto nelze spolehlive realizovat na urovni aplikacniho Windows API, predevsim sledovani otevreni souboru a pozadavek na realny cas notifikaci techto zmen. Bylo by treba napsal kernel filter driver a z neho to pak prenaset do "user" aplikacniho modu (pomoci overlapped DeviceIoControl volani). Takhle to dela Process Monitor, podrobnosti zde.

Trida FileSystemWatcher je patrne zalozena na ReadDirectoryChangesW. Napriklad notifikace FILE_NOTIFY_CHANGE_LAST_ACCESS muze byt zakazana z duvodu lepsiho vykonu NTFS.

K cemu to ma cele slouzit ?

Komentáře

  • dzejkob : Pokud je zakázáno, tak se povolí. Kernel filter driver je už moc přehnané. Měl by (doufám) stačit filesystemwatcher. Je mi jasné, že to nemusí být 100% - proto tam musí být nějaká zadní vrátka. 12.6.2013
  • Petr Voneš : Kdyz to nemusi byt zcela aktualni (realtime), pak asi opravdu staci FileSystemWatcher s tim, ze kdyz je delsi dobu "idle", vyplati se udelat scan cele adresarove struktury (nemusi byt najednou, treba po skupinach adresaru, idealne se na to hodi TPL). Ty notifikace pres API nejsou z principu zcela spolehlive a nekdy se muze takova udalost pro dany soubor ztratit, pokud je hodne zmen najednou. 17.6.2013
  • Honza Břešťan : Spis nez TPL bych na to hodil Quartz.NET. Nechat udalosti, at se vystreluji, a k tomu jednou za nejaky interval pustit scan. 17.6.2013
  • dzejkob : No core část již mám hotovou. Obsahuje to dva watchery, jeden pro soubory, druhý pro adresáře (jinak nejde rozlišit u OnDelete zda šlo o adresář, nebo soubor). Je důležité, aby to mělo na druhé straně uloženou celou strukturu včetně UIDs (uid není definované implicitně, nicméně při prvním dotazu se vytvoří a uloží k souboru/složce natrvalo). Pak se kumulují události do zásobníku a pokud se 2 sekundy nic neděje, tak se dávkově pošlou na rozhraní (v okamžiku kdy se odesílá, tak se události opět kumulují). Je třeba ošetřit několik věcí - za prvé, pokud se soubor maže, tak to musí zjistit UID podle cesty co je uložené v databázi - pak pokud se zachytí dvě události smazání + vytvoření se stejným UID, tak se akce transformuje na přesun. Funguje to překvapivě velice dobře - umí to přesuny souborů, struktur, podstruktur, přejmenování atd. - watchery mají větší buffer size a dokáží zachytit hodně události. Syncrhonizace celých stromů ani není potřeba. Problém nastane pouze v případě, že by někdo kopíroval v jeden okamžik stovky souborů a složek - což se dít nebude. 18.6.2013

Pro zobrazení všech 4 odpovědí se prosím přihlaste:

Rychlé přihlášení přes sociální sítě:

Nebo se přihlaste jménem a heslem:

Zadejte prosím svou e-mailovou adresu.
Zadejte své heslo.