LOG megjelenítése Android APP-ban C# Xamarin-nal

LOG megjelenítése Android APP-ban C# Xamarin-nal
2017-02-08T01:49:51+01:00
2017-07-05T12:42:23+02:00
2022-12-04T16:10:36+01:00
PizzaProgram
Tisztelt C# profik!

- Van már készen olyan LOG-goló rendszer, amivel lehetséges egyszerű módon megjeleníteni a felhasználó felé, mi történik az adott programban, vagy az abból indított háttér szolgáltatásban?
- Vagy külön kell írni egy fájl-ban / SQlite-ban tároló / visszaolvasó rutint?
Furcsának találom, hogy minden Info/Warning üzenet CSAK a VS2015 debug ablakában tekinthető meg, és csak ha nem "release" fordítás.
- Lehet esetleg ezt közvetlenül az APP-ból kiolvasni, amit

Log.i(Now() + ' .. valami');
módon a kódba ékeltünk, és megjeleníteni  egy Listában?

Példa:

13:45:27.269 .. Megnyomtad a "Beállítások" gombot. 13:45:55.123 .. Új paraméterek elmentve 13:45:59.322 .. START gomb = Háttér Szolgáltatás indítása... 13:46.01.354 .. HIBA! Az elsődleges HOST nem válaszolt: 192.168.5.65
Köszönöm a válaszokat!
Mutasd a teljes hozzászólást!
Szeretném megosztani mindenkivel ezt az egyszerű fájl-logger kódot.
A "Pictures" könyvtárba ment naponta egy fájlt, hogy könnyen hozzáférhető legyen. Amennyire tudtam, optimalizáltam, hogy csak minimális erőforrás igénye legyen.

using System; using System.IO; namespace LGR { // ********************************************************************* // C# Xamarin File Logger // ... writes log strings into Pictures / LogSubDir folder. // .. turn OFF by setting ACTiVE=false // Opens a new file every day ! yyyy-MM-dd // WARNING : it does NOT delete old log files :( // ********************************************************************* public static class FLogger { // MODIFY to Turn ON / OFF logger private static bool ACTIVE = true; // true = TURN ON file-logger private const string LogSubDir = "myLOGs"; // it will save the log files to this directory in "Pictures/..." private static DateTime LastDate; private static string dir = ""; private static string filename; public static void WriteLog(string message, Int16 debugLevel = 3) { if (!ACTIVE) return; // EXIT if (FLogger.dir == "") { dir = Android.OS.Environment.GetExternalStoragePublicDirectory(Android.OS.Environment.DirectoryPictures) + "/" + FLogger.LogSubDir + "/"; if (! Directory.Exists(dir)) Directory.CreateDirectory(dir); } var N = DateTime.Now; if (FLogger.LastDate != N.Date) { FLogger.filename = dir + "lg_" + string.Format("{0:yyyy-MM-dd}.log", N); FLogger.LastDate = N.Date; } string ToFile = string.Format("{0:HH:mm:ss.fff}", N) + " " + message + System.Environment.NewLine; try { string f = FLogger.filename; // need for debug > can not see FLogger.f.... if (! File.Exists(f) ) { File.Create(f); } File.AppendAllText(f, ToFile); } catch (Exception ex) { } } } }
Mutasd a teljes hozzászólást!

  • Amit készen találsz, azok a különböző logging library-k (ahogy nézem, pl. Serilog-nak is van Xamarin Sink-je). Ezek leveszik a terhet sok munkáról (formátum, metaadatok - esemény helye, időpontja, szintje -, szálkezelés, absztrakt tárolás - file, XML, adatbázis -, stb.), viszont a log feldolgozása abszolút a fejlesztő feladata, hiszen egyáltalán nem triviális, hogy mit kezdesz vele (esetedben a felhasználónak akarod mutogatni, más meg csak az adminnak).
    Mutasd a teljes hozzászólást!
  • Igen, köszönöm, ezt én is megtaláltam már 3 napja, csakhogy:
    1.) hiába telepítettem fel,
    Successfully installed 'Serilog.Sinks.Xamarin 0.1.29' to ...
    2.) hiába adtam hozzá az elejéhez:

    using Serilog.Sinks.Xamarin;
    3.) Több hibát is ír a fordító:
    Log.Logger = new LoggerConfiguration() .WriteTo.AndroidLog() .Enrich.WithProperty(Constants.SourceContextPropertyName, "MyCustomTag") .CreateLogger();
    Error    CS0117    'Log' does not contain a definition for 'Logger'
    Error    CS0246    The type or namespace name 'LoggerConfiguration' could not be found (are you missing a using directive or an assembly reference?)
    Error    CS0103    The name 'Constants' does not exist in the current context

    4.) Ha sikerülne is túllépni ezeken, akkor sem találtam SEHOL példát arra, hogy lehetne KIOLVASNI a beleírt üzeneteket.
    Mutasd a teljes hozzászólást!
  • Fordító hibák: javaslom, hogy kezdd a kézikönyvvel!

    Pl. itt

    Error CS0117 'Log' does not contain a definition for 'Logger'
    nyilván nincs hozzáadva a namespace a forrásodban.

    Kiolvasás: természetesen ez attól függ, hova tárolod. Neked kell megírni a kódot ehhez.

    A Serilog egy általános logger, a Sink-ek az output-ok.

    Ha te a UI-n akarod megjeleníteni a log bejegyzéseket, én egy custom Sink-et készítenék (implementálod az ILogEventSink interface-t), így egy helyen tudod kezelni a bejövő log-okat (pl. elküldöd egy eseményben, amire feliratkozik az UI) + konfigurálhatsz egy második Sink-et, ahol letárolod azokat.

    Rugalmas és gyors. De neked kell tudnod, mire van szükséged.
    Mutasd a teljes hozzászólást!
  • You may forget this following line in project.json

    "Serilog.Extensions.Logging": "1.0.0",
    Mutasd a teljes hozzászólást!
  • Végül 3 megoldás maradt:
    1.) Egy egyszerű update:

    public static void update (string NewLogLine) { try { LOGlist.Add (new LOGitem () { Title = DateTime.Now.ToString ("HH:mm:ss.fff") + " " + NewLogLine }); if (LOGlist.Count > 100) { LOGlist.RemoveAt(0); } adapter.update(LOGlist); listV.SetSelection(listV.Adapter.Count - 1); } catch {} }

    2.) Emellett készült egy File-logger:

    // ********************************************************************* // C# Xamarin File Logger // ... writes log strings into Pictures / LogSubDir folder. // Opens a new file every day ! yyyy-MM-dd // WARNING : it does NOT delete old log files :( // ********************************************************************* public static class FLogger { // MODIFY to Turn ON / OFF logger private static bool ACTIVE = true; // true = TURN ON file-logger public const string LogSubDir = "LOGs"; // it will save the log files to this directory Pictures/... public static string ToFile = ""; public static DateTime LastDate; public static string dir = ""; public static string filename; public static void WriteLog(string message, Int16 debugLevel = 3) { if (!ACTIVE) return; // EXIT if (FLogger.dir == "") { dir = Android.OS.Environment.GetExternalStoragePublicDirectory(Android.OS.Environment.DirectoryPictures) + "/" + FLogger.LogSubDir + "/"; if (! Directory.Exists(dir)) Directory.CreateDirectory(dir); } var N = DateTime.Now; if (FLogger.LastDate != N.Date) { FLogger.filename = dir + "log_" + string.Format("{0:yyyy-MM-dd}.txt", N); FLogger.LastDate = N.Date; } string ToFile = string.Format("{0:yyyy-MM-dd hh:mm:ss}", N) + " " + message + System.Environment.NewLine; try { string f = FLogger.filename; // need for debug > can not see FLogger.f.... if (! File.Exists(f) ) { File.Create(f); } File.AppendAllText(f, ToFile); } catch (Exception ex) { } } }
    3.) És végül arra jutottam, hogy a igazán jól akarom megcsinálni, akkor előbb utóbb át kell írni ezt a kettőt SQLight alapúra. Mert onnan könnyebb szűrni, stb.

    A SeriLog-gal nem mentem semmire, csak egy csomó időt elpazaroltam rá, amíg működésre próbáltam bírni. :(
    Mutasd a teljes hozzászólást!
  • Ezt a szenvedést valóban megúszhattad volna SQLite-al ahol egy jól irányzott package-el pillanatok alatt működésre bírod és használod
    SQLite-net Official Portable Library
    Mutasd a teljes hozzászólást!
  • Te is jókor szólsz :(
    Az SQL-es megoldásnál viszont azt nem tudom még, (feltéve ha tényleg nekiállok implementálni,) hogy honnan tudja a Frontend Lista, hogy frissítenie kellene ?
     2-3 Másodpercenként csinál egy SELECT-et, amit egy Timer indít? Kicsit gázos megoldásnak tűnik.
    Köszi a segítséget ;)
    Mutasd a teljes hozzászólást!
  • Mondjuk ha van egy jól fésült réteges szerkezetű arhitektúrád, valahol csak ki tudod azt az eseményt csatolni, amikor a perzisztens rétegbe írsz, és ott mentesz egy időpontot, amit tud pollingolni akármi, akárhogy, vagy értesíteni akármit

    Másrészt egy Xamarin iskolapélda MVVM-el, ObservableCollection-okkal meg az INotifyPropertyChanged -el tárgyalásával kezd, ahol nem kell gondolkodnod egy UI lista frissítésén (elvileg) ... Persze ezeknek akkor van értelme ha a Xamarin tényleg arra van használva amire való (PCL) nem pedig csak mint platform amin lehet Android app-okat írogatni
    Mutasd a teljes hozzászólást!
  • Bár xamarinban nem vagyok otthon, de androidra fejlesztettem már néhány dolgot.
    Szóval a listview adatpeterének van egy notifyDataSetChanged() metódusa. Ezt ha meghívod amikor írsz az sqliteba akkor a listview frissülni fog.
    Mutasd a teljes hozzászólást!
  • Szia bup!
     Lehet, hogy én értek valamit félre, de ha a háttér szolgáltatás beleír valamit az SQL-be, akkor utána hogyan kapcsolódik a Frontend Context-hez, hogy riassza?
    Merthogy (ahogy én látom) pont abból adódik az egész probléma, hogy külön fut a két process!
    Mutasd a teljes hozzászólást!
  • K_ edves Attis!

    MVVM-el, ObservableCollection-okkal meg az INotifyPropertyChanged

    Ebből egy szót sem értek :D
    Pont az a bajom, hogy egy ennyire egyszerű feladatnak "de míííéééért" kell ennyire bonyolultan megvalósíthatónak lennie?

    ha a Xamarin tényleg arra van használva amire való (PCL)

    Mi az a PCL ?

    Én eddig VS2015-öt kizárólag Unity Editornak használtam. Kényszerből tértem át a C#-ra, mert hiába írtam meg Delphi alatt az egész programot tokkal vonóval pikk-pakk 2 hét alatt, utólag jöttem rá, hogy az Android folyton kilövi a háttérből, és 3 hónappal később az akkor megjelenő 6.0ás Android-on a Delphi XE8 alatt fordított APP már el sem indult! SDK frissítés pedig meggátolja a compile-t.
    VS2015-ben legalább pár nap késedelemmel frissítik az SDK-t, így már akár 8.0-ra is fordíthatnék most azonnal. (Bár most konkrétan a 7.1.1 van fent, és 6.0-ás készüléken tesztelem.)
    Mutasd a teljes hozzászólást!
  • A Xamarin egy cross platform. A PCL vagy Shared részbe tesszük azt a kódot (Portable Class Library (PCL) vs Shared Projects - Xamarin Help) amit nem kell adott platformhoz igazítani.

    Kérdésedből itélve akkor lényegében csak annyiban "használsz" Xamarin-t hogy lehetővé teszi a C#-ban való kódolást Androidra.

    Úgyhogy tekints el korábbi hozzászólásomtól :)

    Véleményem szerint ez a legrosszabb kombináció. Se nem használod ki az előnyét a Xamarinnak, se nem kapod Xamarin/C#-ban mindazt a képességet és tudásbázist mint amit Java*-ban megkapnál.

    *Kotlin lesz az új hype
    Mutasd a teljes hozzászólást!
  • Bocsi én ertettem felre. Azt gondoltam ugyan abban a ctxben vagyunk. Erdemes lehet utananezni meg  a broadcast kuldesnek es a broadcast receiverekne.
     service kuld egy broadcast intentet, amire feliratkozol egy receiverrel es lekezeled.
    Mutasd a teljes hozzászólást!
  • " ... broadcast küldés ..."
    Igen, ezzel szándékozom éppen próbálkozni...
    Végre frissítették a Xamarin oldalán a guide-okat, és már egész normálisan van végre elmagyarázva minden.
    Majd letöltöm a példaprogit, és az alapján kisilabizálom, hogy lenne a legjobb.

    Amit viszont nem értek, hogy mindenhol az olvasom, hogy az intent-ek sokkal lassabbak, mint a message-ek, mégis szinte minden példánál intent-eket használnak. ??

    A legnagyobb kihívás most éppen az lenne, hogy szétszedjem a progit 2 külön részre, hogy külön process-ként fusson a FrontEnd, meg a Service.
    Sajnos, ha csak ennyit csinálok:

    [Service(IsolatedProcess=true)]
    Az kiakasztja. :(
    Na de míííééééért ?
    Mutasd a teljes hozzászólást!
  • A Xamarin egy cross platform.

     :D :D ... igen, én is benyeltem a marketing blabla-t, ezért kezdtem el abban csinálni. Na és persze azért, mert 3 éve tanulgatom a C#-ot + már egyébként is fent volt a VS2015 a maga X Gigájával a C:\ -n.
    Azután rá kellett jönnöm, hogy kb 5%-át tudnám a kódnak "közösnek" nevezni egy Android és bármely más között, (iOS, Lumia ...) mert:
    1. Az Android Service-k meg az intent-ek úgy tűnik nekem, hogy Teljesen platform specifikusak
    2. A "call-receive" funkciók szintén

    Lehet, hogy van olyan alkalmazástípus, ahol valóban ki lehet használni a PLC megvalósítással a hangoztatott 90-95%-ot, de erre szerintem (és ezért mindenki meg fog kövezni, már tudom előre... ) SOKKAL jobb a Unity.
    Mutasd a teljes hozzászólást!
  • Mint írtam, jelenleg a Xamarin tudásának kis részét használod csak. Lényegében platformfüggően fejlesztesz, egy az egyben ugyanazt csinálod mintha Android Studio-ba Java-ban kódolásnál, csak C#-ra átfordított Java-s osztályokkal, így nem csodálom hogy szűkebbek a lehetőségeid.

    Unity itt akkor lenne analógia, ha azt mondanád hogy Unity-ban C#-ban direct DirectX hívásokat kezdeményezel, és nem használod ki a Unity motor tudását.
    Mutasd a teljes hozzászólást!
  • Szeretném megosztani mindenkivel ezt az egyszerű fájl-logger kódot.
    A "Pictures" könyvtárba ment naponta egy fájlt, hogy könnyen hozzáférhető legyen. Amennyire tudtam, optimalizáltam, hogy csak minimális erőforrás igénye legyen.

    using System; using System.IO; namespace LGR { // ********************************************************************* // C# Xamarin File Logger // ... writes log strings into Pictures / LogSubDir folder. // .. turn OFF by setting ACTiVE=false // Opens a new file every day ! yyyy-MM-dd // WARNING : it does NOT delete old log files :( // ********************************************************************* public static class FLogger { // MODIFY to Turn ON / OFF logger private static bool ACTIVE = true; // true = TURN ON file-logger private const string LogSubDir = "myLOGs"; // it will save the log files to this directory in "Pictures/..." private static DateTime LastDate; private static string dir = ""; private static string filename; public static void WriteLog(string message, Int16 debugLevel = 3) { if (!ACTIVE) return; // EXIT if (FLogger.dir == "") { dir = Android.OS.Environment.GetExternalStoragePublicDirectory(Android.OS.Environment.DirectoryPictures) + "/" + FLogger.LogSubDir + "/"; if (! Directory.Exists(dir)) Directory.CreateDirectory(dir); } var N = DateTime.Now; if (FLogger.LastDate != N.Date) { FLogger.filename = dir + "lg_" + string.Format("{0:yyyy-MM-dd}.log", N); FLogger.LastDate = N.Date; } string ToFile = string.Format("{0:HH:mm:ss.fff}", N) + " " + message + System.Environment.NewLine; try { string f = FLogger.filename; // need for debug > can not see FLogger.f.... if (! File.Exists(f) ) { File.Create(f); } File.AppendAllText(f, ToFile); } catch (Exception ex) { } } } }
    Mutasd a teljes hozzászólást!
  • Megjegyzés:
     - EZ nem a jó megoldás az adott problémára, azon vélhetően csak egy SQL adatbázis fog igazán segíteni.
     - A júzer nem láthatja az eseményeket, csak akkor, ha külön megnyitja a fájlt. (Pl. egy TotalCommander-rel)
    Mutasd a teljes hozzászólást!
Tetszett amit olvastál? Szeretnél a jövőben is értesülni a hasonló érdekességekről?
abcd