Avatar billede mungojerrie Nybegynder
01. februar 2005 - 13:26 Der er 23 kommentarer og
1 løsning

xml log writer - fejler ved afslutning

Hej

Har fundet dette kode på nettet og har testet det på min egen app, men log filen får aldrig en slut-tag, som den jo skal for at være valid xml. Er der nogen der kan se fejlen ??

---------------------------------------------------------------

/*
* ErrorLogWriter class: XML error log writer
*
* Authors:        R. LOPES
* Contributors:    R. LOPES
* Created:        23 October 2002
* Modified:        24 October 2002
*
* Version:        1.0
*/

using System;
using System.IO;
using System.Xml;
using System.Text;
using System.Diagnostics;
using System.Runtime.CompilerServices;

namespace transVikali {
    /// <summary>
    /// ErrorLogWriter class
    /// </summary>
    public class ErrorLogWriter:TextWriter{
        // Variables
        private bool Disposed;
        private XmlTextWriter Writer;

        // Constructor
        public ErrorLogWriter(string FilePath){
            Disposed=false;
            Writer=new XmlTextWriter(FilePath,Encoding.Unicode);

            // Write header
            Writer.Formatting=Formatting.Indented;
            Writer.WriteStartDocument();
            Writer.WriteStartElement("error");
            Writer.Flush();
        }

        // Destructor (equivalent to Finalize() without the need to call base.Finalize())
        ~ErrorLogWriter(){
            Dispose(false);
            }

        // Free resources immediately
        protected override void Dispose(bool Disposing)
        {
            if(!Disposed)
            {
                if(Disposing)
                {
                    // Close file
                    if(Writer!=null)
                    {
                        // Write footer
                        Writer.WriteEndElement();
                        Writer.WriteEndDocument();
                        Writer.Flush();
                        Writer.Close();
                        Writer=null;
                    }
                }
                // Disposed
                Disposed=true;
                // Parent disposing
                base.Dispose(Disposing);
            }
        }
        // Close the file
        public override void Close(){
            // Write footer
            Writer.WriteEndElement();
            Writer.WriteEndDocument();
            Writer.Flush();
            // Free resources
            Dispose(true);
            GC.SuppressFinalize(this);
            }

        // Implement Encoding() method from TextWriter
        public override Encoding Encoding{
            get{
                return(Encoding.Unicode);
                }
            }

        // Implement WriteLine() method from TextWriter (remove MethodImpl attribute for single-threaded app)
        // Use stack trace and reflection to get the calling class and method
        [MethodImpl(MethodImplOptions.Synchronized)]
        public override void WriteLine(string Txt){
            Writer.WriteStartElement("event");
            Writer.WriteStartElement("time");
            Writer.WriteString(DateTime.Now.ToLongTimeString());
            Writer.WriteEndElement();
            Writer.WriteStartElement("class");
            Writer.WriteString(new StackTrace().GetFrame(2).GetMethod().ReflectedType.FullName);
            Writer.WriteEndElement();
            Writer.WriteStartElement("method");
            Writer.WriteString(new StackTrace().GetFrame(2).GetMethod().ToString());
            Writer.WriteEndElement();
            Writer.WriteStartElement("text");
            Writer.WriteString(Txt);
            Writer.WriteEndElement();
            Writer.WriteEndElement();
            Writer.Flush();
            }
        }
    }
Avatar billede arne_v Ekspert
01. februar 2005 - 13:31 #1
Får du kaldt Close metoden ?
Avatar billede mungojerrie Nybegynder
01. februar 2005 - 17:12 #2
hej arne, jeg havde vist lidt travlt da jeg postede ovenstående.

Havde nemlig fundet en anden udgave af klassen som ses nedenunder, hvor der er lavet lidt om på Close metoden, dog fejler denne her på linjen:

FileInfo fiMXF = new FileInfo(FilePath);

Filen eksisterer ikke, der peges her:
Directory.GetCurrentDirectory()+@"\data\error\Error.xml";


----------------------------------------------------------------------
using System;
using System.IO;
using System.Xml;
using System.Text;
using System.Diagnostics;
using System.Runtime.CompilerServices;

namespace transVikali
{
    ///
    /// ErrorLogWriter class
    ///
    public class ErrorLogWriter:TextWriter
    {


        // Variables
        private bool Disposed;
        private XmlDocument doc;
        private string FileLocation;

        // Constructor
        public ErrorLogWriter(string FilePath)
        {
            if(FilePath=="")
            {
                FileLocation = Directory.GetCurrentDirectory()+@"\data\error\Error.xml";
            }
            else
            {
                FileLocation = FilePath;
            }

            Disposed = false;

            doc = new XmlDocument();
            FileInfo fiMXF = new FileInfo(FilePath);
            if ( fiMXF.Exists )
            {
                doc.Load(FilePath);
            }
            else
            {
                XmlDeclaration xmldecl;
                xmldecl = doc.CreateXmlDeclaration("1.0",null,null);
                XmlElement oRoot = doc.CreateElement("error");
                doc.AppendChild(xmldecl);
                doc.AppendChild(oRoot);
            }
        }

        // Destructor (equivalent to Finalize() without the need to call base.Finalize())
        ~ErrorLogWriter()
        {
            Dispose(false);
        }


        // Free resources immediately
        protected override void Dispose(bool Disposing)
        {
            if(!Disposed)
            {
                if(Disposing){}

                // Moved from Close to Dispose Method
                doc.Save(FileLocation);

                // Close file
                doc=null;

                // Disposed
                Disposed=true;
                // Parent disposing
                base.Dispose(Disposing);
            }
        }

        // Close the file
        public override void Close()
        {
            // Free resources
            Dispose(true);
            GC.SuppressFinalize(this);
        }

        // Implement Encoding() method from TextWriter
        public override Encoding Encoding
        {
            get
            {
                return(Encoding.Unicode);
            }
        }

        // Implement WriteLine() method from TextWriter (remove MethodImpl attribute for single-threaded app)
        // Use stack trace and reflection to get the calling class and method
        [MethodImpl(MethodImplOptions.Synchronized)]
        public override void WriteLine(string Txt)
        {
            XmlNode oRoot = doc.DocumentElement;//LastChild.NextSibling;

            XmlElement Event = doc.CreateElement("event");

            XmlElement Time = doc.CreateElement("time");
            XmlElement Class = doc.CreateElement("class");
            XmlElement Method = doc.CreateElement("method");
            XmlElement Text = doc.CreateElement("text");


            XmlText TimeText= doc.CreateTextNode(DateTime.Now.ToString());
            XmlText ClassText= doc.CreateTextNode(new StackTrace().GetFrame(2).GetMethod().ReflectedType.FullName);
            XmlText MethodText= doc.CreateTextNode(new StackTrace().GetFrame(2).GetMethod().ToString());
            XmlText ValueText= doc.CreateTextNode(Txt);


            Time.AppendChild(TimeText);
            Event.AppendChild(Time);

            Class.AppendChild(ClassText);
            Event.AppendChild(Class);

            Method.AppendChild(MethodText);
            Event.AppendChild(Method);

            Text.AppendChild(ValueText);
            Event.AppendChild(Text);
            oRoot.AppendChild(Event);
        }
    }
}
Avatar billede arne_v Ekspert
01. februar 2005 - 20:31 #3
FileInfo fiMXF = new FileInfo(FilePath);

virker fint hos mig selvom filen eksisterer
Avatar billede arne_v Ekspert
01. februar 2005 - 20:32 #4
GetFrame(2) giver null hvis der ikke er nok stak.

Og det er farligt !
Avatar billede mungojerrie Nybegynder
01. februar 2005 - 20:43 #5
--> kommentar kl 01/02-2005 20:31:10 :  det virker da underligt at jeg så får fejl...
--> sidste kommentar: Hvad kan man gøre anderledes så ? Og kender du evt til andre log klasser, der logger som xml og så ikke er alt for store ??
Avatar billede arne_v Ekspert
01. februar 2005 - 20:51 #6
Skal :

FileInfo fiMXF = new FileInfo(FilePath);

ikke være:

FileInfo fiMXF = new FileInfo(FileLocation);

?
Avatar billede mungojerrie Nybegynder
01. februar 2005 - 21:15 #7
Jo selvfølgelig (doughh!!!)

Et andet spg, bliver en constructor ikke automatisk kaldt når man instatierer et object af constructorens klasse ? Lige som i java ?
Avatar billede arne_v Ekspert
01. februar 2005 - 21:17 #8
Jo.
Avatar billede mungojerrie Nybegynder
01. februar 2005 - 21:34 #9
okay, synes bare ikke lige min constructor blev kaldt da jeg debuggede - men det kan jeg nu nemt komme ud over. Er mere interesseret i hvad jeg kan gøre ved disse to kald, hvis du siger det kan få programmet til at fejle:

XmlText ClassText= doc.CreateTextNode(new StackTrace().GetFrame(2).GetMethod().ReflectedType.FullName);
            XmlText MethodText= doc.CreateTextNode(new StackTrace().GetFrame(2).GetMethod().ToString());
Avatar billede arne_v Ekspert
01. februar 2005 - 21:45 #10
Hvis ikke der er tilpas mange kald, så er der jo ikke en GetFrame(2) !
Avatar billede mungojerrie Nybegynder
01. februar 2005 - 22:11 #11
så hvis jeg ikke kalder med GetFrame(2) og i stedet bare bruger GetFrame(), duer det så ? Må sige jeg er lidt på bar bund, når det kommer til stacken
Avatar billede arne_v Ekspert
01. februar 2005 - 22:17 #12
Vi tager lige et eksempel:

using System;
using System.Diagnostics;

namespace E12
{
    class MainClass
    {
        private static void Sub2()
        {
            StackTrace trace = new StackTrace(true);
            for(int i = 0; i < trace.FrameCount; i++)
            {
                Console.WriteLine(i + " " + trace.GetFrame(i).GetMethod().Name);
            }
        }
        private static void Sub1()
        {
            Sub2();
        }
        public static void Main(string[] args)
        {
            Sub1();
        }
    }
}

output:

0 Sub2
1 Sub1
2 Main
Avatar billede arne_v Ekspert
01. februar 2005 - 22:17 #13
og et svar
Avatar billede mungojerrie Nybegynder
01. februar 2005 - 22:32 #14
er det den eneste måde hvorpå jeg kan få fat på den klasse som har kaldt Console.Error ??
Avatar billede arne_v Ekspert
01. februar 2005 - 22:36 #15
Ikke forstået.

Ovenstående skulle illustere hvad de 2 betød.
Avatar billede mungojerrie Nybegynder
01. februar 2005 - 22:41 #16
jeg går udfra at denne del finder frem til klassens navn som kaldte Console.Error:

new StackTrace().GetFrame(2).GetMethod().ReflectedType.FullName
Avatar billede arne_v Ekspert
01. februar 2005 - 22:46 #17
Den går 2 niveauer tilbage i kalde stakken.

Jævnfør mit eksempel.

Om det er noget kdoe der kalder Console.Error ved jeg ikke. Det fremgår ikke
af den postede kode.
Avatar billede mungojerrie Nybegynder
01. februar 2005 - 22:55 #18
nej, det har du selvfølgelig ikke set :-)

Jeg instantierer et objekt af klassen ErrorLogWriter fra min main metode i programmet;

        static ErrorLogWriter elw = null;
        [STAThread]
        static void Main(string[] args)
        {
            elw = new ErrorLogWriter("");
            Console.SetError(elw);
            }
Avatar billede arne_v Ekspert
01. februar 2005 - 23:02 #19
Og hvordan bliver der så skrevet noget ?
Avatar billede mungojerrie Nybegynder
01. februar 2005 - 23:08 #20
når jeg fra en anden klasse tjekker eksempelvis et bib for filer:

        public static void ReadFolder(){
            string path = Directory.GetCurrentDirectory() + IMPORT_PATH;
            try
            {
                // Obtain the file system entries in the directory path.
                string[] directoryEntries =
                    Directory.GetFileSystemEntries(path);

                foreach (string str in directoryEntries)
                {
                              //Test
                    Console.Out.WriteLine(str);
                }
            }
            catch (ArgumentNullException)
            {
                Console.Error.WriteLine("Path is a null reference.");
            }
Avatar billede arne_v Ekspert
01. februar 2005 - 23:13 #21
klasseX metodeY -> klasseZ ReadFolder -> ErrorLogWriter WriteLine

skulle jeg umiddelbart mene at

0 = ErrorLogWriter WriteLine
1 = klasseZ ReadFolder
2 = klasseX metodeY

Er det ikke havd du får ?
Avatar billede mungojerrie Nybegynder
01. februar 2005 - 23:32 #22
Det tjekker jeg lige i morgen, nu skal jeg vist se dyner....
Avatar billede mungojerrie Nybegynder
03. februar 2005 - 10:43 #23
Hej igen....må tilstå jeg har skodet det fundne kode og lavet min egen log klasse.
Og den kunne jeg da godt tænke mig at høre nogle kommentarer til, da den skulle kunne klare en del kald, ikke fordi jeg regner med mit program der bruger log klassen vil fejle, men fordi mit program skal overvågne et bibliotek, som et andet program skal dumpe filer til og disse filer kan jo godt være fejlbehæftede. Så hvis der er nogle kommentarer hører jeg dem gerne.
Avatar billede mungojerrie Nybegynder
03. februar 2005 - 10:44 #24
Klassen kommer her:

Den bliver kaldt med : LogWriter.logInfo() eller med LogWriter.logError()

-------------------------------

using System;
using System.IO;
using System.Xml;
using System.Text;

namespace transVikali
{
    /// <summary>
    /// Summary description for LogWriter.
    /// </summary>
    public class LogWriter
    {

        private static XmlDocument doc;
        private static string FileLocation;
        private static string ErrorFileName = "error_";
        private static string InfoFileName = "info_";
        private static string FileExtension = ".xml";
        private static string INFO_LOG_TYPE = "info";
        private static string ERROR_LOG_TYPE = "error";
        protected const string ERROR_PATH = @"\data\error\";   
        protected const string INFO_PATH = @"\data\info\";
        private static string APPEND_DATE = DateTime.Today.Date.ToShortDateString();
        private static XmlNode node;

        public static void logError(string method, string text){
            FileLocation = Directory.GetCurrentDirectory()+ ERROR_PATH;
            if(!DoesFileExist(getFileLocation(ERROR_LOG_TYPE), ERROR_LOG_TYPE))
            {
                CreateLogFile(getFileLocation(ERROR_LOG_TYPE), ERROR_LOG_TYPE);
                AppendToLog(ERROR_LOG_TYPE, method, text);
            }
            else
            {
                AppendToLog(ERROR_LOG_TYPE, method, text);
            }

        }

        private static void CreateLogFile(string FileLocation, string logtype)
        {
            string rootElement = "info";
           
            if(logtype==ERROR_LOG_TYPE)rootElement = "Error";

            doc = new XmlDocument();
            XmlDeclaration xmldecl = doc.CreateXmlDeclaration("1.0",Encoding.Unicode.ToString(),null);
            XmlElement root = doc.CreateElement(rootElement);
            doc.AppendChild(root);
            XmlTextWriter writer  = new XmlTextWriter(FileLocation, System.Text.Encoding.ASCII);
            writer.Formatting = Formatting.Indented;
            doc.Save(writer);
            writer.Flush();
            writer.Close();
        }

        public static void logInfo(string method, string text)
        {
            FileLocation = Directory.GetCurrentDirectory()+ INFO_PATH;
            if(!DoesFileExist(getFileLocation(INFO_LOG_TYPE), INFO_LOG_TYPE))
            {
                CreateLogFile(getFileLocation(INFO_LOG_TYPE), INFO_LOG_TYPE);
                AppendToLog(INFO_LOG_TYPE, method, text);
            }
            else
            {
                AppendToLog(INFO_LOG_TYPE, method, text);
            }
        }

        private static XmlNode WriteToLog(string method, string text)
        {
            node = doc.CreateNode(XmlNodeType.Element, "event", "");
            XmlElement failedMethod = doc.CreateElement("method");
            XmlText failedMethodText = doc.CreateTextNode(method);
            failedMethod.AppendChild(failedMethodText);
            node.AppendChild(failedMethod);

            XmlElement time = doc.CreateElement("time");
            XmlText timeText = doc.CreateTextNode(DateTime.Now.ToLongTimeString());
            time.AppendChild(timeText);
            node.AppendChild(time);
   
            XmlElement textElement = doc.CreateElement("text");
            XmlText textElementText = doc.CreateTextNode(text);
            textElement.AppendChild(textElementText);
            node.AppendChild(textElement);

            return node;
        }

        private static void AppendToLog(string logtype, string method, string text)
        {
            try
            {
                doc = new XmlDocument();
                doc.Load(getFileLocation(logtype));
                doc.DocumentElement.AppendChild(WriteToLog(method, text));
                doc.Save(getFileLocation(logtype));
            }
            catch (System.NullReferenceException e)
            {
                Console.WriteLine("AppendToLog failed" + e.ToString());
            }
            catch (System.IO.FileNotFoundException ef){
                Console.WriteLine("AppendToLog failed" + ef.ToString());
            }
        }


        private static string getFileLocation(string logtype)
        {
            string tempFileLocation = "";
            if(logtype == ERROR_LOG_TYPE)
            {
                tempFileLocation = FileLocation + ErrorFileName + APPEND_DATE + FileExtension;
            }
            else
            {
                tempFileLocation = FileLocation + InfoFileName + APPEND_DATE + FileExtension;
            }
            return tempFileLocation;
        }

        private static bool DoesFileExist(string FileLocation, string logtype)
        {
            try
            {
                if (File.Exists(getFileLocation(logtype)))
                {
                    return true;
                }
            }
            catch (System.IO.FileNotFoundException e)
            {
                Console.WriteLine(e.ToString());
            }
            return false;
        }

    }
}
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
IT-kurser om Microsoft 365, sikkerhed, personlig vækst, udvikling, digital markedsføring, grafisk design, SAP og forretningsanalyse.

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester