Home » Community » Forums » Web Development » Is this possible? if so, how...?
  Intel sponsors gamedev.net search:   
[Control Panel] [Register] [Bookmarks] [Who's Online] [Active Topics] [Stats] [FAQ] [Search]

Add Forum to Favorites |  Send Topic To a Friend | View Forum FAQ | Track this topic


 Last Thread Next Thread 
 Is this possible? if so, how...?
Post New Topic  Post Reply 
Hi all,

I'll have to admit up front - I was never a fan of "hand writing" website's with HTML. I did a bit about 5yrs ago when I was younger and thought it was particularly cool , but haven't touched it since then.

Anyway... I have an HTML log file generated by our game engine. It's very simple - just a huge colour coded table. Green=comment, Blue=event, Orange=warning, Red=error. Each row in the table has a time index, a source module, line number and message.

The forum won't allow me to put in the HTML table code to demonstrate, but if its of any interest to anyone, heres an example:
<table border="1" width="100%" cellspacing="0" cellpadding="0" bordercolorlight="#000000" bordercolordark="#ffffff" bordercolor="#000000">
<tr>

<td width="20%" bgcolor="#000000"><font size="2" face="Arial" color="#FFFFFF">[b]Time Index[/b]</font></td>
<td width="21%" bgcolor="#000000"><font size="2" face="Arial" color="#FFFFFF">[b]Source File[/b]</font></td>
<td width="4%" bgcolor="#000000"><font size="2" face="Arial" color="#FFFFFF">[b]Line[/b]</font></td>
<td width="55%" bgcolor="#000000"><font size="2" face="Arial" color="#FFFFFF">[b]Comment[/b]</font></td>
</tr>
<tr>
<font size="2" face="Arial" color="#000000">
<td width ="20%" bgcolor="#8080ff"><font size="2" face="Arial" color="#000000">01secs 73ms</font></td>
<td width ="21%" bgcolor="#8080ff"><font size="2" face="Arial" color="#000000">CLogFile.cpp</font></td>
<td width ="4%" bgcolor="#8080ff"><font size="2" face="Arial" color="#000000">101</font></td>

<td width ="55%" bgcolor="#8080ff"><font size="2" face="Arial" color="#000000">Log File Opened</font></td>
</font>
</tr>
</table>



Thing is, with maximum debug enabled (often the case while we're testing) the single log file can get pretty damn huge pretty quickly. This is only a problem in that it's more difficult for a human to read through...

So, the question...
Could I, without getting too heavy into XML/CSS/XSLT/whatever modify the outputted page so that (for example) there were a set of checkboxes/lists at the top of the page so the user can filter the information dynamically.

e.g. "Show only errors" or "Show only events". Even a "Show only messages from ??? module" would be nice..

So, is this possible without having to extensively integrate/implement other technologies? I'm prepared to put some new stuff in - but this isn't a major feature request (yet!) so I can't spare too many of my hours working on it .

Could anyone here tell me:
a) if the above is realistically possible
b) any buzzwords/technologies that I need to do my homework on to implement this?

Thanks in advance,
Jack


Jack Hoxley [ Forum FAQ | Revised FAQ | MVP Profile | Developer Journal ]

 User Rating: 1947   |  Rate This User  Send Private MessageView ProfileView Journal Report this Post to a Moderator | Link

What you'd need to do is output the debug data to a database first, then use a webpage to dynamically retrieve data from the database that corresponds to any filters you wish to apply to the information.


www.EdCatchpole.com - Tank!, Save VC, Pacman 3D, Pong-Man Mobile

 User Rating: 1073   |  Rate This User  Send Private MessageView ProfileView GD Showcase Entries Report this Post to a Moderator | Link

Quote:
output the debug data to a database first, then use a webpage to dynamically retrieve data

Are we talking full-blown databases like MySQL and friends? or could it be a simple text-file database thats distributed alongside the HTML front end?

Cheers,
Jack


Jack Hoxley [ Forum FAQ | Revised FAQ | MVP Profile | Developer Journal ]

 User Rating: 1947   |  Rate This User  Send Private MessageView ProfileView Journal Report this Post to a Moderator | Link

I know very little about javascript, but I'm guessing there's a good chance that you could simply use that to show/hide various items. Something like a javascript for loop responding to a checkbox click that goes through all the elements of the page, and if their properties have the correct color, make them visible/invisible. Any decent browser should have no problem with that.

 User Rating: 1787   |  Rate This User  Send Private MessageView ProfileView Journal Report this Post to a Moderator | Link

Interesting - I'll look into the JScript approach.

I've just realised, looking through my code, that I can change just a few lines and get a full XML database outputted instead.. which could be a slightly better route given the fact that everyone loves XML and the world is an infinitely happier place because of its existance

Jack


Jack Hoxley [ Forum FAQ | Revised FAQ | MVP Profile | Developer Journal ]

 User Rating: 1947   |  Rate This User  Send Private MessageView ProfileView Journal Report this Post to a Moderator | Link

Why not output it as XML and make an HTML page that will filter the XML data?

 User Rating: 1520   |  Rate This User  Send Private MessageView Profile Report this Post to a Moderator | Link

Quote:
Original post by Etnu
Why not output it as XML and make an HTML page that will filter the XML data?

I'm thinking this is what I want to do.

Can I use XSLT to have some sort of conditional selection?

I'll have a read through some XSL stuff online when I get a chance - got some training notes lying around somewhere as well. I've got the log file spitting out XML now with a style sheet that generates a nearly identical output to the one I had before.

Cheers,
Jack


Jack Hoxley [ Forum FAQ | Revised FAQ | MVP Profile | Developer Journal ]

 User Rating: 1947   |  Rate This User  Send Private MessageView ProfileView Journal Report this Post to a Moderator | Link

Here's a solution that would require nothing other than a web browser. To get your conditional viewing will require a minor change in the XSLT file, but it's fairly simple to do. Of course, if you're running a web server you could create a simple admin page to view your logs.

Imagine you have your logfile.xml

<?xml version="1.0" ?>
<?xml-stylesheet type="text/xsl" href="logviewer.xsl" ?>

<log>
	<logentry timeIndex="00:01:73" type="event">
		<sourceFile line="101">CLogFile.cpp</sourceFile>
		<comment>Log File Opened</comment>
	</logentry>
	<logentry timeIndex="00:02:35" type="error">
		<sourceFile line="123">CTextureLoader.cpp</sourceFile>
		<comment>Error opening texture</comment>
	</logentry>
</log>





And the XSLT file to view it logviewer.xsl:

<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:variable name="eventType" select="'all'" /> 

<xsl:template match="/">
	
	<html>
		<head>
			<title>Logfile Viewer</title>
		</head>
		<body>
			<h1>Logfile</h1>

			<p>Showing events of type: <xsl:copy-of select="$eventType" /></p>

			<table width="95%">
				<tr style="font-weight: bold">
					<td>Type</td><td>Time Index</td><td>Source 

File</td><td>Line</td><td>Comment</td>
				</tr>
				<xsl:apply-templates select="log" />
			</table>
		</body>

	</html>
</xsl:template>

<xsl:template match="log">
	<xsl:apply-templates select="logentry" />
</xsl:template>

<xsl:template match="logentry">
	<xsl:if test="$eventType= 'all' or @type= $eventType">
	<tr>
		<td><xsl:value-of select="@type" /></td><td><xsl:value-of select="@timeIndex" 

/></td><td><xsl:value-of select="sourceFile" /></td><td><xsl:value-of select="sourceFile/@line" 

/></td><td><xsl:value-of select="comment" /></td>
	</tr>
	<tr>
		<td colspan="6"><br /></td>
	</tr>
	</xsl:if>		
</xsl:template>

</xsl:stylesheet>





To change the type, go to the xsl:variable at the top and change the value between 'all', 'error' and 'event' to view the types.

Of course, this would be nicely formatted and you'd probably want to add more conditions.

Edit: Forgot to add, open the xml file in your browser. IE works, not tried FF.

 User Rating: 1902   |  Rate This User  Send Private MessageView ProfileView Journal Report this Post to a Moderator | Link

Quote:
Here's a solution that would require nothing other than a web browser.

Thats absolutely perfect - thanks very much for that . ++Rating.

What you've given me should work for 90% of what I want, and I'm sure I can figure out the rest (if possible) from google... but if you've got a chance to look at this again...

<xsl:variable name="eventType" select="'all'" />

Are you aware of any way to feed this in as a parameter rather than have it statically embedded in the document?

I guess I'm thinking something like ASP (?) where you might have:
file://C:/my_game/my_log/logfile.xml?eventType='all'

If such a thing was possible, I'd look at creating a "linking" web page where you might have:

<ahref="...?eventType='error'">Click here to view only errors
<ahref="...?eventType='warning'">Click here to view only warnings

so that the end user doesn't even really need to know whats happening under the covers...

Cheers,
Jack


Jack Hoxley [ Forum FAQ | Revised FAQ | MVP Profile | Developer Journal ]

 User Rating: 1947   |  Rate This User  Send Private MessageView ProfileView Journal Report this Post to a Moderator | Link

I didn't think it was possible, but according to this post it does indeed seem like it can be done.

I can't get it to work however, at least - not with a local file.

 User Rating: 1902   |  Rate This User  Send Private MessageView ProfileView Journal Report this Post to a Moderator | Link

Interesting... Thanks for linking that in.

Gives me something to start working with, so fingers crossed I can come up with something.

I'll post back here with what I come up with if I can get it working (might be of use to anyone else..)

Thanks for the help!
Jack


Jack Hoxley [ Forum FAQ | Revised FAQ | MVP Profile | Developer Journal ]

 User Rating: 1947   |  Rate This User  Send Private MessageView ProfileView Journal Report this Post to a Moderator | Link

Please, let me know how you get on. You've given me a couple of ideas for my own logger ;)

 User Rating: 1902   |  Rate This User  Send Private MessageView ProfileView Journal Report this Post to a Moderator | Link

Quote:
Original post by evolutional
Please, let me know how you get on. You've given me a couple of ideas for my own logger ;)

Will do - should hopefully get some time to work through it when I get home from my "real job" tonight .

btw, as a somewhat unrelated note - Email notify - wrong user name quoted? is something I just started in the other forum with regards to this thread. Unlikely, but maybe it'll make some sense to you???

Cheers,
Jack


Jack Hoxley [ Forum FAQ | Revised FAQ | MVP Profile | Developer Journal ]

 User Rating: 1947   |  Rate This User  Send Private MessageView ProfileView Journal Report this Post to a Moderator | Link

I just thought of another way. Create a local html file with some javascript functions in it (using XmlHttpRequest and Microsoft.XMLDOM). This file would act as your index page eg: "Show Errors", "Show All", etc

When you click on a 'link' a javascript function will be called to load the XML document and pass a parameter to the XSL file for transforming.

Give me a few and I'll try and demonstrate what I mean.

 User Rating: 1902   |  Rate This User  Send Private MessageView ProfileView Journal Report this Post to a Moderator | Link

It still won't allow you to pass a parameter on your querystring, you'll need a webserver for that... But this method gives you a viewer page which will dynamically sort the XML file for you.

The source kills the forum layout, so download the code here

Let me know if this was useful to you.

 User Rating: 1902   |  Rate This User  Send Private MessageView ProfileView Journal Report this Post to a Moderator | Link

Quote:
Let me know if this was useful to you.


I haven't managed to get as far as implementing your example in my own XSL file (I'm still working through the basic structure stuff), however looking at your example it should do what I want it to.

I'm hoping to do some more complex filtering based on multiple parameters - but I can easily see that one going wrong . If it does, I'll stick with the simpler single-param example you provided.

As a side note, I had to authorize MSIE to use the associated ActiveX controls before it'd do anything with your viewer.html file.

Also, it doesn't seem to work in the slightest with FireFox. You can click on the links to your hearts content but nothing happens. I'm wondering if this is XP-SP2 stopping FireFox from using ActiveX controls and silently failing. Alternatively, it might just be the code you provided is somehow MSIE specific??

I'll keep you updated as to what mine works out as. I'll see if I can get away with posting my robust solution here - provided I can disclose the information and the forum itself can host the pure text (I have no webspace currently).

Cheers,
Jack


Jack Hoxley [ Forum FAQ | Revised FAQ | MVP Profile | Developer Journal ]

 User Rating: 1947   |  Rate This User  Send Private MessageView ProfileView Journal Report this Post to a Moderator | Link

Yeah, the basic code there is MSIE only. I think there's some Mozilla functions to do a similar thing, but I'll need to look them up. I also think creating the DOM with a different method would overcome the activex warning (I had to do the same thing) - but this was just for a demonstration. If it's what you need give me a shout and I'll try and find the cross-browser functions.



Oli Wilkinson, MCTS SQL Server 2005


Personal Sites: [Journal] | [evolutional] | [Manta-X] | [jsInvaders] | [GameMonkey articles]
Useful links: [TinyXml] | [W3c XML Spec] | [SpiderMonkey javascript] | [boost]
Useful links: [Psionic's 3d Game Resources] | [NaturalDocs] | [Code on the Cob] | [AngelCode Reference DB]


Longing for the good ol' days, where people made games and not engines

 User Rating: 1902   |  Rate This User  Send Private MessageView ProfileView Journal Report this Post to a Moderator | Link

I posted some links in this thread about making this cross-platform.

Gotta be said... I bloody love javascript and XML <3

 User Rating: 1902   |  Rate This User  Send Private MessageView ProfileView Journal Report this Post to a Moderator | Link

Then use some CSS on it, and presto!


Rob Loach [Website] [Projects] [Contact]

 User Rating: 1932   |  Rate This User  Send Private MessageView ProfileView JournalView GD Showcase Entries Report this Post to a Moderator | Link

Quote:
Original post by Rob Loach
Then use some CSS on it, and presto!

CSS would be good, but I don't know anything much about that

I'll add that to my never-ending list of things to look at..

Cheers,
Jack


Jack Hoxley [ Forum FAQ | Revised FAQ | MVP Profile | Developer Journal ]

 User Rating: 1947   |  Rate This User  Send Private MessageView ProfileView Journal Report this Post to a Moderator | Link

Quote:
Original post by jollyjeffers
Quote:
Original post by Rob Loach
Then use some CSS on it, and presto!
CSS would be good, but I don't know anything much about that
Just view the source of evolutional's website and you'll understand the power of CSS .


Rob Loach [Website] [Projects] [Contact]

 User Rating: 1932   |  Rate This User  Send Private MessageView ProfileView JournalView GD Showcase Entries Report this Post to a Moderator | Link

Hah, I was just going to point out that there's an article on this, but it seems you two wrote it..

Excellent job =)

 User Rating: 1315   |  Rate This User  Send Private MessageView Profile Report this Post to a Moderator | Link

Quote:
Just view the source of evolutional's website and you'll understand the power of CSS

Will look into it. I get the idea of CSS and roughly how it works, just have never used the syntax/design before..

Quote:
Original post by Fuzztrek
Hah, I was just going to point out that there's an article on this, but it seems you two wrote it..

This very thread is where it all started

Cheers,
Jack


Jack Hoxley [ Forum FAQ | Revised FAQ | MVP Profile | Developer Journal ]

 User Rating: 1947   |  Rate This User  Send Private MessageView ProfileView Journal Report this Post to a Moderator | Link

By accident, I just discovered today on my computer at work that McAfee (the antivirus software) uses the same technologies for its log files.

Two files are created:
Agent_BE00010.xml
and
FrameworkLog.xsl

(Actually, there are more, old log entries are moved to a backup log file)

Since the content is straightforward and allows one to get an idea what is possible without setting up everything that is discussed in the mentioned article, I thought it might be useful for other readers to try it out themselves.

Therefore, below is the (trimmed down) content of both files. Create the two files with the filenames mentioned above and paste the content (see below) in it.
Then open Agent_BE00010.xml using Internet Explorer (seems not compatible with Firefox). You should get a nice looking log overview (but not as extensive as the one set up in the article) with sorting capabilities.

regards,
Rabarberski




Agent_BE00010.xml
----------------
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="FrameworkLog.xsl"?>
<naLog> 
  <ComputerName>BE00010</ComputerName>                                                                                                                                                                                                         
  <Log component="8" time="2005-07-12T20:39:33" type="3">Loading update configuration from: Catalog.xml</Log>
  <Log component="64" time="2005-07-12T20:39:35" type="3">Scheduler: Task [Deployment] is finished</Log>
  <Log component="2" time="2005-07-12T22:38:41" type="3">Collecting Properties</Log>
  <Log component="8192" time="2005-07-12T22:38:48" type="3">Agent is looking for events to upload</Log>
  <Log component="16" time="2005-07-13T10:39:14" type="3">Upload success and no package to receive</Log>
  <Log component="8192" time="2005-07-13T10:39:14" type="3">No package received from ePO Server</Log>
</naLog>




FrameworkLog.xsl
-----------------
<?xml version="1.0" encoding="UTF-8"?>
 <xsl:stylesheet xmlns:xsl="http://www.w3.org/TR/WD-xsl" 
     xmlns:html="http://www.w3.org/TR/REC-html40"
     result-ns="">
  <xsl:template match="/">
    <HTML>
      <HEAD>
        <style>
          BODY {margin:0;}
          .bg {font:8pt Arial; background-color:white; color:black; }
          H1 {font:bold 14pt Arial; width:100%;}
          .titleText {font:14pt Arial; padding-left:10px; color:white}
          A {color:white}
          .row {font:8pt tahoma;}
          .header {font:bold 8pt tahoma; cursor:hand;}
		  .Error    {background-color:#ffcccc; color:#000000}
		  .Warning  {background-color:#ffcc99; color:#000000}
          .Info   {background-color:#FFFFFF; color:#000000}
          .Detail   {background-color:#ffffff; color:#999999}
        </style>
      </HEAD>

      <SCRIPT><xsl:comment><![CDATA[
        function sort(field)
        {
          sortField.value = field;
          <!-- set cursor to watch here? -->
          listing.innerHTML = source.documentElement.transformNode(stylesheet);
        }
      ]]></xsl:comment></SCRIPT>

      <SCRIPT for="window" event="onload"><xsl:comment><![CDATA[
        stylesheet = document.XSLDocument;
        source = document.XMLDocument;
        sortField = document.XSLDocument.selectSingleNode("//@order-by");
      ]]></xsl:comment></SCRIPT>

      <BODY>

        <TABLE width="100%" cellspacing="0" style="background-color:#cc0033">
          <TR>
            <TD width="100%" align="left" valign="center" class="titleText"  style="border-bottom: 3px solid #000000; padding-bottom:8px">
              McAfee Agent Activity Log<BR/>
              <div class="row">
              View debug logs: FrameSvc
              <xsl:element name="A">
                 <xsl:attribute name="HREF">
                 Agent_<xsl:value-of select="//naLog/ComputerName"/>.log
                 </xsl:attribute>current</xsl:element> /
              <xsl:element name="A">
                 <xsl:attribute name="HREF">
                 Agent_<xsl:value-of select="//naLog/ComputerName"/>_backup.log
                 </xsl:attribute>previous</xsl:element>,
              NaPrdMgr
              <xsl:element name="A">
                 <xsl:attribute name="HREF">
                 PrdMgr_<xsl:value-of select="//naLog/ComputerName"/>.log
                 </xsl:attribute>current</xsl:element> /
              <xsl:element name="A">
                 <xsl:attribute name="HREF">
                 PrdMgr_<xsl:value-of select="//naLog/ComputerName"/>_backup.log
                 </xsl:attribute>previous</xsl:element>
              </div>
            </TD>
          </TR>
          <TR>
            <TD class="bg" valign="top" colspan="2">
              <DIV id="listing"><xsl:apply-templates match="naLog"/></DIV>
            </TD>
          </TR>
        </TABLE>    
      </BODY>
    </HTML>
  </xsl:template>

  <xsl:template match="naLog">
    <TABLE style="background-color:white">
      <THEAD>
        <TD> <DIV class="header" onClick="sort('@time')"><u>Date and Time</u></DIV></TD>
        <TD> <DIV class="header" onClick="sort('@type')"><u>Type</u></DIV></TD>
        <TD> <DIV class="header" onClick="sort('@component')"><u>Component</u></DIV></TD>
        <TD> <DIV class="header" onClick="sort('.')"><u>Message</u></DIV></TD>
      </THEAD>

      <xsl:for-each select="Log" order-by="@time">
        <TR>

            <xsl:choose>
				<xsl:when test="@type[. = 1]">
					<xsl:attribute name="class">Error</xsl:attribute>
				</xsl:when>

				<xsl:when test="@type[. ='2']">
					<xsl:attribute name="class">Warning</xsl:attribute>
				</xsl:when>

				<xsl:when test="@type[. ='3']">
					<xsl:attribute name="class">Info</xsl:attribute>
				</xsl:when>

				<xsl:when test="@type[. ='4']">
					<xsl:attribute name="class">Detail</xsl:attribute>
				</xsl:when>
			</xsl:choose>


          <TD><DIV class="row" style="text-align:left"><xsl:apply-templates select="@time"/></DIV></TD>
		  <TD valign="bottom"><DIV class="row" style="text-align:left"><xsl:apply-templates select="@type"/></DIV></TD>
  		  <TD valign="bottom"><DIV class="row" style="text-align:left"><xsl:apply-templates select="@component"/></DIV></TD>
		  <TD valign="bottom"><DIV class="row" style="text-align:left"><xsl:value-of select="."/></DIV></TD>
		</TR>
      </xsl:for-each>
    </TABLE>
  </xsl:template>



  <xsl:template match="@time">
		<xsl:eval>MyGetDateTime();</xsl:eval>
  </xsl:template>

  <xsl:template match="@type">
		<xsl:eval>GetType();</xsl:eval>
  </xsl:template>

  <xsl:template match="@component">
		<xsl:eval>GetComponent();</xsl:eval>
  </xsl:template>
	
  

  <xsl:script language="JScript">
	<![CDATA[
	function GetType()
	{
		var StrRet;
		switch ( this.Value )

		{
			case "1":
				StrRet = "Error";
				break;

			case "2":
				StrRet = "Warning";
				break;

			case "3":
				StrRet = "Info";
				break;

			case "4":
				StrRet = "Detail";
				break;
		}

		return StrRet;

	}

	function GetComponent()
	{
		var StrRet;
		switch ( this.Value )

		{

			case "1":
				StrRet = "Logging";
				break;

			case "2":
				StrRet = "Management";
				break;

			case "4":
				StrRet = "Updater";
				break;

			case "8":
				StrRet = "Script";
				break;

			case "16":
				StrRet = "Internet Manager";
				break;

			case "32":
				StrRet = "Test Harness";
				break;

			case "64":
				StrRet = "Scheduler";
				break;

			case "128":
				StrRet = "Policy Harness";
				break;

			case "256":
				StrRet = "User Space Controller";
				break;

			case "512":
				StrRet = "Framework Factory";
				break;

			case "1024":
				StrRet = "Framework Service";
				break;

			case "2048":
				StrRet = "Policy Manager";
				break;

			case "4096":
				StrRet = "Product Manager";
				break;

			case "8192":
				StrRet = "Agent";
				break;

			case "16384":
				StrRet = "Listen Server";
				break;

			case "32768":
				StrRet = "Framework Plugin";
				break;

			case "65536":
				StrRet = "Site Manager";
				break;
		}

		return StrRet;
	}


	function MyGetDateTime() 
	{
		var Strs;
		var Str1;
		var StrRet;
		regExpression = /-|T|:/;
		Str1 = this.nodeTypedValue;
		d = new Date();
		Strs = Str1.split(regExpression);

		d.setFullYear (Strs[0]);

		d.setMonth(Strs[1]-1);
		d.setDate(Strs[2]);

		d.setHours(Strs[3]);
		d.setMinutes(Strs[4]);
		d.setSeconds(Strs[5]);
		
		return d.toLocaleString();
		
	} ]]>
 </xsl:script>
</xsl:stylesheet>





edit: source tags -SiCrane

[Edited by - Rabarberski on July 17, 2005 10:38:01 AM]

 User Rating: 1015   |  Rate This User  Send Private MessageView Profile Report this Post to a Moderator | Link

All times are ET (US)

Post Reply
 Last Thread Next Thread 
Forum Rules:
You may not post new threads
You may post replies
You may not edit your posts
You may not use HTML in your posts
Jump To:
Administrative Options: