/// <summary>
        /// Called whenever Padarn encounters an internal error
        /// </summary>
        /// <param name="errorInfo">Information about the specific error</param>
        public virtual void LogPadarnError(string errorInfo, LogDataItem dataItem)
        {
            Debug.WriteLine(errorInfo);

            try
            {
                if (ServerConfiguration == null)
                {
                    return;                              // the configuration is null, so we have no output path
                }
                if (!ServerConfiguration.LoggingEnabled)
                {
                    return;
                }
                if (dataItem == null)
                {
                    return;
                }

                if (!dataItem.ServerConfiguration.LoggingEnabled)
                {
                    return;
                }

                using (TextWriter writer = File.AppendText(Path.Combine(ServerConfiguration.LogFileFolder, "PadarnErrors.txt")))
                {
                    writer.WriteLine(errorInfo);
                    writer.Flush();
                }
            }
            catch
            {
                // swallow errors to prevent blowing up on log failures (like out of space)
            }
        }
        /// <summary>
        /// Called whenever padarn get a request to access a page
        /// </summary>
        /// <param name="dataItem">Data related to the access call</param>
        public virtual void LogPageAccess(LogDataItem dataItem)
        {
            string page = dataItem.PageName;

            // do nothing if logging is not enabled
            if (!dataItem.ServerConfiguration.LoggingEnabled)
            {
                return;
            }

            // see if extension filtering is on, if so see if we should get filtered
            if (dataItem.ServerConfiguration.LogExtensions.Count > 0)
            {
                string ext = Path.GetExtension(page);
                if (!dataItem.ServerConfiguration.LogExtensions.Contains(ext))
                {
                    return;
                }
            }

            try
            {
                DateTime now = DateTime.Now;

                // if we're not the first run, we need to do some checking
                if (m_lastLogDay != DateTime.MinValue)
                {
                    // check to see if we're in a new day
                    if ((now.Day != m_lastLogDay.Day) || ((TimeSpan)(now - m_lastLogDay)).Days > 0)
                    {
                        // new day, new file
                        m_currentFileName = string.Format("LOG_{0}-{1}-{2}.txt", now.Year, now.Month, now.Day);
                    }
                }
                else
                {
                    m_currentFileName = string.Format("LOG_{0}-{1}-{2}.txt", now.Year, now.Month, now.Day);
                }

                m_currentFileName = Path.Combine(dataItem.ServerConfiguration.LogFileFolder, m_currentFileName);

                // // create the log file if it doesn't exist
                if (!File.Exists(m_currentFileName))
                {
                    using (StreamWriter writer = File.CreateText(m_currentFileName))
                    {
                        // do nothing - just create the file
                    }
                }

                page = page.Replace(dataItem.ServerConfiguration.DocumentRoot, "");
                string ip = dataItem.RemoteClientIP.ToString();

                using (StreamWriter writer = File.AppendText(m_currentFileName))
                {
                    // log here
                    // format is as follows:
                    //
                    // [ISO date] page <client ip> client browser
                    //
                    writer.WriteLine(
                        string.Format("[{0}] {1} <{2}> {3}",
                                      now.ToString("yyyy-MM-dd hh:mm:ss"),
                                      page,
                                      ip.Substring(0, ip.IndexOf(':')),
                                      dataItem.Headers["user-agent"])
                        );
                }
            }
            catch
            {
                // swallow errors to prevent blowing up on log failures (like out of space)
            }
        }