Search Results

Search found 20659 results on 827 pages for 'var'.

Page 12/827 | < Previous Page | 8 9 10 11 12 13 14 15 16 17 18 19  | Next Page >

  • Why is the file /var/crash/_usr_lib_empathy_empathy-chat.1000.upload empty?

    - by user43816
    I just experienced an unusual crash: I tried to click on a name entry in the contact list of Empathy. A crash happened. Usually I am asked then if I'd like to report the error to Launchpad, and Launchpad opens. This time the error message was: "Excuse me. Ubuntu 12.04 noticed an internal error. If you notice further problems try to restart your computer. Send an error report to Launchpad to help removing this problem?" This time Launchpad did not open automatically. A new window opened and I could read the relevant error report. Later I found the error report in the file /var/crash/_usr_lib_empathy_empathy-chat.1000.crash. Why went the course of action this time differently from other crashes? Why is the file /var/crash/_usr_lib_empathy_empathy-chat.1000.upload empty?

    Read the article

  • How large should I make root, home, usr, var, and tmp partitions?

    - by Teddy Okidoki
    i install ubuntu server 10.04, have 64 Gb VHD. And want to separate partitions in this mode: /dev/xvda0 p on swap (2 Gb) /dev/xvda1a0 e on /boot (128 Mb) /dev/xvda1a1 e on / type ffs (local) /dev/xvda1a2 e on /usr type ffs (local, nodev) /dev/xvda1a3 e on /tmp type ffs (local, nodev) /dev/xvda1a4 e on /var/log type ffs (local, nodev) /dev/xvda1a5 e on /var type ffs (local, nodev, nosuid) /dev/xvda1a6 e on /home type ffs (local, nodev, nosuid, with quotas) /dev/xvda2 p on /new (local, nodev, nosuid, noexec) with rest of space ~50Gb. But i'ma stuck, and don't know what size to give to each folder. Also i want to encrypt partitions. Thank you for any tips. EDIT: System need minimum size, here will be installed about 10 apps like ufw, apache,mysql, chkrootkit and so on.

    Read the article

  • C#: AutoFixture refactoring

    - by Thomas Jaskula
    Hello, I started to use AutoFixture http://autofixture.codeplex.com/ as my unit tests was bloated with a lot of data setup. I was spending more time on seting up the data than to write my unit test. Here's an example of how my initial unit test looks like (example taken from cargo application sample from DDD blue book) [Test] public void should_create_instance_with_correct_ctor_parameters() { var carrierMovements = new List<CarrierMovement>(); var deparureUnLocode1 = new UnLocode("AB44D"); var departureLocation1 = new Location(deparureUnLocode1, "HAMBOURG"); var arrivalUnLocode1 = new UnLocode("XX44D"); var arrivalLocation1 = new Location(arrivalUnLocode1, "TUNIS"); var departureDate1 = new DateTime(2010, 3, 15); var arrivalDate1 = new DateTime(2010, 5, 12); var carrierMovement1 = new CarrierMovement(departureLocation1, arrivalLocation1, departureDate1, arrivalDate1); var deparureUnLocode2 = new UnLocode("CXRET"); var departureLocation2 = new Location(deparureUnLocode2, "GDANSK"); var arrivalUnLocode2 = new UnLocode("ZEZD4"); var arrivalLocation2 = new Location(arrivalUnLocode2, "LE HAVRE"); var departureDate2 = new DateTime(2010, 3, 18); var arrivalDate2 = new DateTime(2010, 3, 31); var carrierMovement2 = new CarrierMovement(departureLocation2, arrivalLocation2, departureDate2, arrivalDate2); carrierMovements.Add(carrierMovement1); carrierMovements.Add(carrierMovement2); new Schedule(carrierMovements).ShouldNotBeNull(); } Here's how I tried to refactor it with AutoFixture [Test] public void should_create_instance_with_correct_ctor_parameters_AutoFixture() { var fixture = new Fixture(); fixture.Register(() => new UnLocode(UnLocodeString())); var departureLoc = fixture.CreateAnonymous<Location>(); var arrivalLoc = fixture.CreateAnonymous<Location>(); var departureDateTime = fixture.CreateAnonymous<DateTime>(); var arrivalDateTime = fixture.CreateAnonymous<DateTime>(); fixture.Register<Location, Location, DateTime, DateTime, CarrierMovement>( (departure, arrival, departureTime, arrivalTime) => new CarrierMovement(departureLoc, arrivalLoc, departureDateTime, arrivalDateTime)); var carrierMovements = fixture.CreateMany<CarrierMovement>(50).ToList(); fixture.Register<List<CarrierMovement>, Schedule>((carrierM) => new Schedule(carrierMovements)); var schedule = fixture.CreateAnonymous<Schedule>(); schedule.ShouldNotBeNull(); } private static string UnLocodeString() { var stringBuilder = new StringBuilder(); for (int i = 0; i < 5; i++) stringBuilder.Append(GetRandomUpperCaseCharacter(i)); return stringBuilder.ToString(); } private static char GetRandomUpperCaseCharacter(int seed) { return ((char)((short)'A' + new Random(seed).Next(26))); } I would like to know if there's better way to refactor it. Would like to do it shorter and easier than that. Thanks in advance for your help.

    Read the article

  • AutoFixture refactoring

    - by Thomas Jaskula
    I started to use AutoFixture http://autofixture.codeplex.com/ as my unit tests was bloated with a lot of data setup. I was spending more time on seting up the data than to write my unit test. Here's an example of how my initial unit test looks like (example taken from cargo application sample from DDD blue book) [Test] public void should_create_instance_with_correct_ctor_parameters() { var carrierMovements = new List<CarrierMovement>(); var deparureUnLocode1 = new UnLocode("AB44D"); var departureLocation1 = new Location(deparureUnLocode1, "HAMBOURG"); var arrivalUnLocode1 = new UnLocode("XX44D"); var arrivalLocation1 = new Location(arrivalUnLocode1, "TUNIS"); var departureDate1 = new DateTime(2010, 3, 15); var arrivalDate1 = new DateTime(2010, 5, 12); var carrierMovement1 = new CarrierMovement(departureLocation1, arrivalLocation1, departureDate1, arrivalDate1); var deparureUnLocode2 = new UnLocode("CXRET"); var departureLocation2 = new Location(deparureUnLocode2, "GDANSK"); var arrivalUnLocode2 = new UnLocode("ZEZD4"); var arrivalLocation2 = new Location(arrivalUnLocode2, "LE HAVRE"); var departureDate2 = new DateTime(2010, 3, 18); var arrivalDate2 = new DateTime(2010, 3, 31); var carrierMovement2 = new CarrierMovement(departureLocation2, arrivalLocation2, departureDate2, arrivalDate2); carrierMovements.Add(carrierMovement1); carrierMovements.Add(carrierMovement2); new Schedule(carrierMovements).ShouldNotBeNull(); } Here's how I tried to refactor it with AutoFixture [Test] public void should_create_instance_with_correct_ctor_parameters_AutoFixture() { var fixture = new Fixture(); fixture.Register(() => new UnLocode(UnLocodeString())); var departureLoc = fixture.CreateAnonymous<Location>(); var arrivalLoc = fixture.CreateAnonymous<Location>(); var departureDateTime = fixture.CreateAnonymous<DateTime>(); var arrivalDateTime = fixture.CreateAnonymous<DateTime>(); fixture.Register<Location, Location, DateTime, DateTime, CarrierMovement>( (departure, arrival, departureTime, arrivalTime) => new CarrierMovement(departureLoc, arrivalLoc, departureDateTime, arrivalDateTime)); var carrierMovements = fixture.CreateMany<CarrierMovement>(50).ToList(); fixture.Register<List<CarrierMovement>, Schedule>((carrierM) => new Schedule(carrierMovements)); var schedule = fixture.CreateAnonymous<Schedule>(); schedule.ShouldNotBeNull(); } private static string UnLocodeString() { var stringBuilder = new StringBuilder(); for (int i = 0; i < 5; i++) stringBuilder.Append(GetRandomUpperCaseCharacter(i)); return stringBuilder.ToString(); } private static char GetRandomUpperCaseCharacter(int seed) { return ((char)((short)'A' + new Random(seed).Next(26))); } I would like to know if there's better way to refactor it. Would like to do it shorter and easier than that.

    Read the article

  • xml appending issue - in ie, chrome browsers

    - by 3gwebtrain
    Hi, i am using this coding for my xml information to append in to html. As well it works fine. but in the ie7,ie8 as well chrome browser it's not propelry. This code work9ing well with firefox,opera, safari.. i unable to find, what is the mistake i made this.. any one help me please? $(function(){ var thisPage; var parentPage; $('ul.left-navi li a').each(function(){ $('ul.left-navi li a').removeClass('current'); var pathname = (window.location.pathname.match(/[^\/]+$/)[0]); var currentPage = $(this).attr('href'); var pathArr = new Array(); pathArr = pathname.split("."); var file = pathArr[pathArr.length - 2]; thisPage = file; if(currentPage==pathname){ $(this).addClass("active"); } }) $.get('career-utility.xml',function(myData){ var receivedData = myData; var myXml = $(myData).find(thisPage); parentPage = thisPage; var overviewTitle = myXml.find('overview').attr('title'); var description = myXml.find('discription').text(); var mainsublinkTitle = myXml.find('mainsublink').attr('title'); var thisTitle = myXml.find("intro").attr('title'); var thisIntro = myXml.find("introinfo").text(); $('<h3>'+overviewTitle+'</h3>').appendTo('.overViewInfo'); $('<p>'+description+'</p>').appendTo('.overViewInfo'); var sublinks = myXml.find('mainsublink').children('sublink'); $('#intro h3').append(thisTitle); $('#intro').append(thisIntro); sublinks.each(function(numsub){ var newSubLink = $(this); var sublinkPage = $(this).attr('pageto'); var linkInfo = $(this).text(); $('ul.career-link').append('<li><a href="'+sublinkPage+'">'+linkInfo+'</a></li>'); }) // alert('thisTitle : '+thisTitle+'thisIntro :'+thisIntro); $(myXml).find('listgroup').each(function(index){ var count = index; var listGroup = $(this); var listGroupTitle = $(this).attr('title'); var shortNote = $(this).attr('shortnote'); var subLink = $(this).find('sublist'); var firstList = $(this).find('list'); $('.grouplist').append('<div class="list-group"><h3>'+listGroupTitle+'</h3><ul class="level-one level' + count + '"></ul></div>'); firstList.each(function(listnum) { $(this).wrapInner('<li>') .find('sublistgroup').wrapInner('<ul>').children().unwrap() .find('sublist').wrapInner('<li>').children().unwrap(); // Append content of 'list' node $('ul.level'+count).append($(this).children()); }); }); }); })

    Read the article

  • How to display values from another website to an new html page?

    - by user3098728
    How to display the value in a new html file from different website? This an example field of values that need to display into new html file and I want to display the said values in the input box (Contract ID) of this page JSFiddle. I have 2 JS code that would display that values, but unfortunately its not working and I dont know how to display that value in html input box. Please help me. Thank you I want to display the said value in this input box: Here the JS file to read the values: function scanLapVerification() { try { var page_title = "Title"; var el = getElement(document, "class", "view-operator-verification-title", ""); if (!el || el.length == 0) return; if (el[0].innerText != page_title) return; var page_title = ''; var el = getElement(document, "class", "workflowActivityDetailPanel", ""); if (el && el.length > 0) { var eltr = getElement(el[0], "tag", "tr", ""); if (eltr && eltr.length > 0) { //Read Contract ID var contractId = { CI: { id: null } }; var con_id = null; for (var i = 0; i < eltr.length; i++) { tr_text = eltr[i].innerText; if (tr_text.substr(0, "Contract ID".length) == "Contract ID") con_id = "CI"; if (con_id && tr_text.substr(0, "Contract ID".length) == "Contract ID") { contractId[con_id].id = tr_text.substr("Contract ID".length + 1, tr_text.length - "Contract ID".length - 1); } } var contract_id = contractId.CI.id; return { content: "cid_check", con_id: con_id }; } return { status: "KO" }; } catch (e) { alert("Exception: scanLapVerification\n" + e.Description); return { status: "KO", message: e }; } }; And here's the 2nd JS that display to a new html page: function scanLapVerification() { chrome.tabs.sendRequest(tabLapVerification, { method: "scanLapVerification" }, function (response) { msgbox("receiveResponse: scanLapVerification " + jsonToString(response, "JSON")); //maintaining state in the background if (response.data.content == "cid_check") { //Popup window features var popupWindow = null; var name; var width = 550; var height = 200; var left = parseInt((screen.availWidth / 2) - (width / 2)); var top = parseInt((screen.availHeight / 2) - (height / 2)); var windowFeatures = "width=" + width + ",height=" + height + ",left=" + left + ",top=" + top + "screenX=" + left + ",screenY=" + top; //Input new address with popup window if (confirm("Does the client has new address?") == true) { popupWindow = window.open('/htmlname.htm', "title", windowFeatures + encodeURIComponent(response.data.contract_id)); popupWindow.focus(); } else { name = ""; } }); }

    Read the article

  • Logrotate not doing any rotation

    - by blizz
    I just set up LogRotate on my RHEL6 server so that it rotates my custom Apache log files. However, it doesn't do anything when i try manually running it. I expect it to rotate the log files "access.log" and "err.log". They have been there for a few days and need to be rotated. Here is the output: [root@pc1 httpd]# logrotate -d -f /etc/logrotate.d/apache reading config file /etc/logrotate.d/apache reading config info for /var/log/httpd/*log /var/www/html/NSLogs/access.log /var/www/html/NSErrorLogs/err.log Handling 1 logs rotating pattern: /var/log/httpd/*log /var/www/html/NSLogs/access.log /var/www/html/NSErrorLogs/err.log forced from command line (no old logs will be kept) empty log files are rotated, old logs are removed considering log /var/log/httpd/access_log log needs rotating considering log /var/log/httpd/error_log log needs rotating considering log /var/www/html/NSLogs/access.log log needs rotating considering log /var/www/html/NSErrorLogs/err.log log needs rotating rotating log /var/log/httpd/access_log, log->rotateCount is 0 dateext suffix '-20131023' glob pattern '-[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]' glob finding old rotated logs failed fscreate context set to unconfined_u:object_r:httpd_log_t:s0 renaming /var/log/httpd/access_log to /var/log/httpd/access_log-20131023 disposeName will be /var/log/httpd/access_log-20131023.gz running postrotate script running script with arg /var/log/httpd/access_log: " /usr/bin/killall -HUP httpd " compressing log with: /bin/gzip removing old log /var/log/httpd/access_log-20131023.gz error: error opening /var/log/httpd/access_log-20131023.gz: No such file or directory rotating log /var/log/httpd/error_log, log->rotateCount is 0 dateext suffix '-20131023' glob pattern '-[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]' glob finding old rotated logs failed fscreate context set to unconfined_u:object_r:httpd_log_t:s0 renaming /var/log/httpd/error_log to /var/log/httpd/error_log-20131023 disposeName will be /var/log/httpd/error_log-20131023.gz running postrotate script running script with arg /var/log/httpd/error_log: " /usr/bin/killall -HUP httpd " compressing log with: /bin/gzip removing old log /var/log/httpd/error_log-20131023.gz error: error opening /var/log/httpd/error_log-20131023.gz: No such file or directory rotating log /var/www/html/NSLogs/access.log, log->rotateCount is 0 dateext suffix '-20131023' glob pattern '-[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]' glob finding old rotated logs failed fscreate context set to unconfined_u:object_r:httpd_sys_rw_content_t:s0 renaming /var/www/html/NSLogs/access.log to /var/www/html/NSLogs/access.log-20131023 disposeName will be /var/www/html/NSLogs/access.log-20131023.gz running postrotate script running script with arg /var/www/html/NSLogs/access.log: " /usr/bin/killall -HUP httpd " compressing log with: /bin/gzip removing old log /var/www/html/NSLogs/access.log-20131023.gz error: error opening /var/www/html/NSLogs/access.log-20131023.gz: No such file or directory rotating log /var/www/html/NSErrorLogs/err.log, log->rotateCount is 0 dateext suffix '-20131023' glob pattern '-[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]' glob finding old rotated logs failed fscreate context set to unconfined_u:object_r:httpd_sys_rw_content_t:s0 renaming /var/www/html/NSErrorLogs/err.log to /var/www/html/NSErrorLogs/err.log-20131023 disposeName will be /var/www/html/NSErrorLogs/err.log-20131023.gz running postrotate script running script with arg /var/www/html/NSErrorLogs/err.log: " /usr/bin/killall -HUP httpd " compressing log with: /bin/gzip removing old log /var/www/html/NSErrorLogs/err.log-20131023.gz error: error opening /var/www/html/NSErrorLogs/err.log-20131023.gz: No such file or directory

    Read the article

  • Giving an Error Object Expected Line 48 Char 1

    - by Leslie Peer
    Giving an Error Object Expected Line 48 Char 1------What did I do wrong??? *Note Line # are for reference only not on Original Web page****** <HTML><HEAD><TITLE></TITLE> <META http-equiv=Content-Type content="text/html; charset=utf-8"> <META content="Leslie Peer" name=author> <META content="Created with Trellian WebPage" name=description> <META content="MSHTML 6.00.6000.16809" name=GENERATOR> <META content=Index name=keywords> <STYLE type=text/css>BODY { COLOR: #000000; BACKGROUND-REPEAT: repeat; FONT-FAMILY: Accent SF, Arial, Arial Black, Arial Narrow, Century Gothic, Comic Sans MS, Courier, Courier New, Georgia, Microsoft Sans Serif, Monotype Corsiva, Symbol, Tahoma, Times New Roman; BACKGROUND-COLOR: #666666 } A { FONT-SIZE: 14px; FONT-FAMILY: Arial Black, Bookman Old Style, DnD4Attack, Lucida Console, MS Serif, MS Outlook, MS Sans Serif, Rockwell Extra Bold, Roman, Star Time JL, Tahoma, Terminal, Times New Roman, Verdana, Wingdings 2, Wingdings 3, Wingdings } A:link { COLOR: #9966cc; TEXT-DECORATION: underline } A:visited { COLOR: #66ff66; TEXT-DECORATION: underline } A:hover { COLOR: #ffff00; TEXT-DECORATION: underline } A:active { COLOR: #ff0033; TEXT-DECORATION: underline } H1 { FONT-SIZE: 25px; COLOR: #9966cc; FONT-FAMILY: Century Gothic } H2 { FONT-SIZE: 20px; COLOR: #ff33cc; FONT-FAMILY: Century Gothic } H3 { FONT-SIZE: 18px; COLOR: #6666cc; FONT-FAMILY: Century Gothic } H4 { FONT-SIZE: 15px; COLOR: #00cc33; FONT-FAMILY: Century Gothic } H5 { FONT-SIZE: 10px; COLOR: #ffff33; FONT-FAMILY: Century Gothic } H6 { FONT-SIZE: 5px; COLOR: #996666; FONT-FAMILY: Century Gothic } </STYLE> line 46-<SCRIPT> line 47- CharNum=6; line 48-var Character=newArray();Character[0]="Larry Lightfoot";Character[1]="Sam Wrightfield";Character[2]="Gavin Hartfild";Character[3]="Gail Quickfoot";Character[4]="Robert Gragorian";Character[5]="Peter Shain"; line 49-var ExChar=newArray();ExChar[0]="Tabor Bloomfield"; line 50-var Class=newArray();Class[0]="MagicUser";Class[1]="Fighter";Class[2]="Fighter";Class[3]="Thief";Class[4]="Cleric";Class[5]="Fighter"; line 51-line 47var ExClass=newArray();ExClass[0]="MagicUser"; line 52-var Level=newArray();Level[0]="2";Level[1]="1";Level[2]="1";Level[3]="2";Level[4]="2";Level[5]="1"; line 53-var ExLevel=newArray();ExLevel[0]="23"; line 54-var Hpts=newArray();Hpts[0]="6";Hpts[1]="14";Hpts[2]="13";Hpts[3]="8";Hpts[4]="12";Hpts[5]="15"; line 55-var ExHpts=newArray();ExHpts[0]="145"; line 56-var Armor=newArray();Armor[0]="Cloak";Armor[1]="Splinted Armor";Armor[2]="Chain Armor";Armor[3]="Leather Armor";Armor[4]="Chain Armor";Armor[5]="Splinted Armor"; line 57-var ExArmor=newArray();ExArmor[0]="Robe of Protection +5"; line 58-var Ac1=newArray();Ac1[0]="0";Ac1[1]="3";Ac1[2]="3";Ac1[3]="4";Ac1[4]="2";Ac1[5]="3"; line 59-var ExAc=newArray();ExAc[0]="5"; line 60-var Armor1b=newArray();Armor1b[0]="Ring of Protection +1";Armor1b[1]="Small Shield";Armor1b[2]="Small Shield";Armor1b[3]="Wooden Shield";Armor1b[4]="Large Shield";Armor1b[5]="Small Shield"; line 61-var ExArmor1b=newArray();ExArmor1b[0]="Ring of Protection +5"; line 62-var Ac2=newArray();Ac2[0]="1";Ac2[1]="1";Ac2[2]="1";Ac2[3]="1";Ac2[4]="1";Ac2[5]="1"; line 63-var ExAc1b=newArray();ExAc1b[0]="5" line 64-var Str=newArray();Str[0]="15";Str[1]="16";Str[2]="14";Str[3]="13";Str[4]="14";Str[5]="13"; line 65-var ExStr=newArray();ExStr[0]=21; line 66-var Int=newArray();Int[0]="17";Int[1]="11";Int[2]="12";Int[3]="13";Int[4]="14";Int[5]="13"; line 67-var ExInt=newArray();ExInt[0]="19"; line 68-var Wis=newArray();Wis[0]="17";Wis[1]="12";Wis[2]="14";Wis[3]="13";Wis[4]="14";Wis[5]="12"; line 69-var ExWis=newArray();ExWis[0]="18"; line 70-var Dex=newArray();Dex[0]="15";Dex[1]="14";Dex[2]="13";Dex[3]="15";Dex[4]="14";Dex[5]="12"; line 71-var ExDex=newArray();ExDex[0]="19"; line 72-var Con=newArray();Con[0]="16";Con[1]="15";Con[2]="16";Con[3]="13";Con[4]="12";Con[5]="10"; line 73-var ExCon=newArray();ExCon[0]="19"; line 74-var Chr=newArray();Chr[0]="16";Chr[1]="14";Chr[2]="13";Chr[3]="12";Chr[4]="14";Chr[5]="13"; line 75-var ExChr=newArray();ExChr[0]="21"; line 76-var Expt=newArray();Expt[0]="45";Expt[1]="21";Expt[2]="16";Expt[3]="18";Expt[4]="22";Expt[5]="34"; line 77-var ExExpt=newArray();ExExpt[0]="245678"; line 78-var ExBp=newArray();ExBp[0]="Unknown";ExBp[1]="Extrademensional Plane World of Amborsia";ExBp[2]="Evil Wizard Banished for Mass Geniocodes"; line 79-</SCRIPT> line 80-</HEAD> line 81-<BODY> Giving an Error Object Expected Line 48 Char 1------What did I do wrong??? *Note Line # are for reference only not on Original Web page******

    Read the article

  • Delete old map markers and load new ones?

    - by pufAmuf
    I'm trying to delete the old markers and load new ones. Here is the code I have that loads certain markers on page load - no issues here: (function() { var customIcons = { 1: { icon: 'redmarker.png', shadow: 'markershadow.png' }, 2: { icon: 'purplemarker.png', shadow: 'markershadow.png' }, 3: { icon: 'silvermarker.png', shadow: 'markershadow.png' }, 4: { icon: 'goldmarker.png', shadow: 'markershadow.png' } }; window.onload = function(){ var MY_MAPTYPE_ID = 'custom'; var stylez = [ { "stylers": [ { "hue": "#00ccff" }, { "saturation": -100 }, { "lightness": 5 } ] },{ } ]; var latlng = new google.maps.LatLng(10, 10); var options = { zoom: 16, center: latlng, panControl: false, zoomControl: false, scaleControl: true, mapTypeControlOptions: { mapTypeIds: [MY_MAPTYPE_ID,google.maps.MapTypeId.SATELLITE] }, mapTypeId: MY_MAPTYPE_ID }; var map = new google.maps.Map(document.getElementById('map'), options); var styledMapOptions = { name: 'Map' }; var jayzMapType = new google.maps.StyledMapType(stylez, styledMapOptions); map.mapTypes.set(MY_MAPTYPE_ID, jayzMapType); var infoWindow = new google.maps.InfoWindow; // Change this depending on the name of your PHP file downloadUrl("getxml.php", function(data) { var xml = data.responseXML; var markers = xml.documentElement.getElementsByTagName("marker"); for (var i = 0; i < markers.length; i++) { var name = markers[i].getAttribute("id"); var address = markers[i].getAttribute("id"); var type = markers[i].getAttribute("venue_type"); var point = new google.maps.LatLng( parseFloat(markers[i].getAttribute("lat")), parseFloat(markers[i].getAttribute("lng"))); var html = "<b>" + name + "</b> <br/>" + address; var icon = customIcons[type] || {}; var marker = new google.maps.Marker({ map: map, position: point, icon: icon.icon, shadow: icon.shadow }); bindInfoWindow(marker, map, infoWindow, html); } }); //BUTTON SWITCHING //////////////////////////////////////////////////////////// //BUTTON SWITCHING //////////////////////////////////////////////////////////// //BUTTON SWITCHING //////////////////////////////////////////////////////////// //BUTTON SWITCHING //////////////////////////////////////////////////////////// //BUTTON SWITCHING //////////////////////////////////////////////////////////// //BUTTON SWITCHING //////////////////////////////////////////////////////////// //BUTTON SWITCHING //////////////////////////////////////////////////////////// jQuery(document).delegate(".topCanBeActive", "click", function( e ) { e.preventDefault(); jQuery(".topCanBeActive").removeClass("topActive"); jQuery(this).addClass("topActive"); switch( this.id ){ case 'all_activity_button': alert("search"); break; case 'events_button': downloadUrl("getxml2.php", function(data) { var xml = data.responseXML; var markers = xml.documentElement.getElementsByTagName("marker"); for (var i = 0; i < markers.length; i++) { var name = markers[i].getAttribute("id"); var address = markers[i].getAttribute("id"); var type = markers[i].getAttribute("venue_type"); var point = new google.maps.LatLng( parseFloat(markers[i].getAttribute("lat")), parseFloat(markers[i].getAttribute("lng"))); var html = "<b>" + name + "</b> <br/>" + address; var icon = customIcons[type] || {}; var marker = new google.maps.Marker({ map: map, position: point, icon: icon.icon, shadow: icon.shadow }); bindInfoWindow(marker, map, infoWindow, html); } }); break; case 'venues_button': alert("venues"); break; case 'search_button': alert("search"); break; } }); //END //////////////////////////////////////////////////////////// //END //////////////////////////////////////////////////////////// //END //////////////////////////////////////////////////////////// //END //////////////////////////////////////////////////////////// //END //////////////////////////////////////////////////////////// //END //////////////////////////////////////////////////////////// //END //////////////////////////////////////////////////////////// //END //////////////////////////////////////////////////////////// } function bindInfoWindow(marker, map, infoWindow, html) { google.maps.event.addListener(marker, 'click', function() { infoWindow.setContent(html); infoWindow.open(map, marker); }); } function downloadUrl(url, callback) { var request = window.ActiveXObject ? new ActiveXObject('Microsoft.XMLHTTP') : new XMLHttpRequest; request.onreadystatechange = function() { if (request.readyState == 4) { request.onreadystatechange = doNothing; callback(request, request.status); } }; request.open('GET', url, true); request.send(null); } function doNothing() {} })(); Now, I created a button section where if you press one button, a different xml file is loaded. Notice the section with the ////////////////////// However, upon clicking the button, nothing happens. The xml file itself is okay and loads the desired data. I also receive no errors in firebug. Any ideas why this happens? Thanks!

    Read the article

  • Errors Code: /var/cache/apt/archives/linux-image-3.8.0-19-generic_3.8.0-19.30~precise1_amd64.deb

    - by user286682
    $ sudo apt-get dist-upgrade Reading package lists... Done Building dependency tree Reading state information... Done Calculating upgrade... Done The following packages will be upgraded: linux-image-3.8.0-19-generic 1 upgraded, 0 newly installed, 0 to remove and 0 not upgraded. 6 not fully installed or removed. Need to get 0 B/47.8 MB of archives. After this operation, 142 MB of additional disk space will be used. Do you want to continue [Y/n]? y (Reading database ... 164064 files and directories currently installed.) Preparing to replace linux-image-3.8.0-19-generic 3.8.0-19.29 (using .../linux-image-3.8.0-19-generic_3.8.0-19.30~precise1_amd64.deb) ... Done. Unpacking replacement linux-image-3.8.0-19-generic ... dpkg: error processing /var/cache/apt/archives/linux-image-3.8.0-19-generic_3.8.0-19.30~precise1_amd64.deb (--unpack): trying to overwrite '/lib/modules/3.8.0-19-generic/kernel/arch/x86/kvm/kvm-intel.ko', which is also in package linux-image-extra-3.8.0-19-generic 3.8.0-19.29 dpkg-deb: error: subprocess paste was killed by signal (Broken pipe) Examining /etc/kernel/postrm.d . run-parts: executing /etc/kernel/postrm.d/initramfs-tools 3.8.0-19-generic /boot/vmlinuz-3.8.0-19-generic run-parts: executing /etc/kernel/postrm.d/zz-update-grub 3.8.0-19-generic /boot/vmlinuz-3.8.0-19-generic Errors were encountered while processing: /var/cache/apt/archives/linux-image-3.8.0-19-generic_3.8.0-19.30~precise1_amd64.deb E: Sub-process /usr/bin/dpkg returned an error code (1) How can I get this update to work?

    Read the article

  • DPKG errors after upgrade to 12.10

    - by James Wulfe
    So I was doing fine then i upgraded my system to 12.10 and now i cant get my system to update all of its packages properly. no matter what i do, cleaning apt cache, manual install using dpkg, etc, i just cant get them to install. what is happening here and how do i fix this. if i would have thought 12.10 would be this much of a hassle i would have never upgraded..... here is a sampling of the code that returns from "apt-get -f install" Preparing to replace usb-modeswitch-data 20120120-0ubuntu1 (using .../usb-modeswitch-data_20120815-1_all.deb) ... /var/lib/dpkg/info/usb-modeswitch-data.prerm: 4: /var/lib/dpkg/info/usb-modeswitch-data.prerm: dpkg-maintscript-helper: Input/output error dpkg: warning: subprocess old pre-removal script returned error exit status 2 dpkg: trying script from the new package instead ... /var/lib/dpkg/tmp.ci/prerm: 4: /var/lib/dpkg/tmp.ci/prerm: dpkg-maintscript-helper: Input/output error dpkg: error processing /var/cache/apt/archives/usb-modeswitch-data_20120815-1_all.deb (--unpack): subprocess new pre-removal script returned error exit status 2 /var/lib/dpkg/info/usb-modeswitch-data.postinst: 7: /var/lib/dpkg/info/usb-modeswitch-data.postinst: dpkg-maintscript-helper: Input/output error dpkg: error while cleaning up: subprocess installed post-installation script returned error exit status 2 Errors were encountered while processing: /var/cache/apt/archives/network-manager_0.9.6.0-0ubuntu7_i386.deb /var/cache/apt/archives/pcmciautils_018-8_i386.deb /var/cache/apt/archives/unity-common_6.10.0-0ubuntu2_all.deb /var/cache/apt/archives/whoopsie_0.2.7_i386.deb /var/cache/apt/archives/usb-modeswitch_1.2.3+repack0-1ubuntu3_i386.deb /var/cache/apt/archives/usb-modeswitch-data_20120815-1_all.deb E: Sub-process /usr/bin/dpkg returned an error code (1) It is also just these 6 packages only. no other packages have given me this kind of trouble. well i should say as of now. It was just 5, but them i got an update for unity, and now unity-common is added to the trouble makers. which prevents me from further upgrading the actual unity package as this package is a dependancy.....

    Read the article

  • If you favor "T *var", do you ever write "T*"?

    - by Roger Pate
    Thinking about where we place our asterisks; how do those that prefer to keep the "pointerness" away from the type and with the identifier (int *i) write code when the identifier is missing? void f(int*); // 1 void f(int *); // 2 The former seems much more common, no matter what your preference when with the identifier. Is this a special case? What makes it an exception? However, the first still isn't universal, because I have seen the latter style. Besides consistency along the lines of "there's always a space with the identifier, so we have one without", are there any other reasons to prefer it? What about casts or array and function types? How would you re-write these: (void*)var /*or*/ (void *)var int[3] /*or*/ int [3] // more relevant in C++ than C: Example<int[3]> void(int) /*or*/ void (int) // more relevant in C++ than C: std::function<void(int)> The latter two would rarely, if ever, be used in C, but are seen with C++ templates.

    Read the article

  • Implementing Camera Zoom in a 2D Engine

    - by Luke
    I'm currently trying to implement camera scaling/zoom in my 2D Engine. Normally I calculate the Sprite's drawing size and position similar to this pseudo code: render() { var x = sprite.x; var y = sprite.y; var sizeX = sprite.width * sprite.scaleX; // width of the sprite on the screen var sizeY = sprite.height * sprite.scaleY; // height of the sprite on the screen } To implement the scaling i changed the code to this: class Camera { var scaleX; var scaleY; var zoom; var finalScaleX; // = scaleX * zoom var finalScaleY; // = scaleY * zoom } render() { var x = sprite.x * Camera.finalScaleX; var y = sprite.y * Camera.finalScaleY; var sizeX = sprite.width * sprite.scaleX * Camera.finalScaleX; var sizeY = sprite.height * sprite.scaleY * Camera.finalScaleY; } The problem is that when the zoom is smaller than 1.0 all sprites are moved toward the top-left corner of the screen. This is expected when looking at the code but i want the camera to zoom on the center of the screen. Any tips on how to do that are welcome. :)

    Read the article

  • SVN Error 403 Forbidden

    - by Chris
    I can't figure this out. I try to import a new project into a svn repository from Netbeans and get 403 Forbidden. I just setup svn on my serverbox today. I can get to it through a browser just fine, though its empty as I haven't imported my project yet. Apache's path for html files is /var/www I setup the svn repo in /var/svn This is the structure of /var/svn [root@localhost svn]# ls -lR /var/svn /var/svn: total 4 drwxrwxrwx 7 apache apache 4096 2010-03-26 10:18 repo /var/svn/repo: total 36 drwxrwxrwx 2 apache apache 4096 2010-03-26 09:47 conf drwxrwxrwx 3 apache apache 4096 2010-03-26 10:18 dav drwxrwsrwx 6 apache apache 4096 2010-03-26 11:19 db -rwxrwxrwx 1 apache apache 2 2010-03-26 09:47 format drwxrwxrwx 2 apache apache 4096 2010-03-26 09:47 hooks drwxrwxrwx 2 apache apache 4096 2010-03-26 09:47 locks -rwxrwxrwx 1 apache apache 229 2010-03-26 09:47 README.txt -rwxrwxrwx 1 apache apache 15 2010-03-26 09:47 svnauth -rwxrwxrwx 1 apache apache 43 2010-03-26 09:48 svnpass /var/svn/repo/conf: total 12 -rwxrwxrwx 1 apache apache 1080 2010-03-26 09:47 authz -rwxrwxrwx 1 apache apache 309 2010-03-26 09:47 passwd -rwxrwxrwx 1 apache apache 2279 2010-03-26 09:47 svnserve.conf /var/svn/repo/dav: total 4 drwxrwxrwx 2 apache apache 4096 2010-03-26 11:19 activities.d /var/svn/repo/dav/activities.d: total 0 /var/svn/repo/db: total 48 -rwxrwxrwx 1 apache apache 2 2010-03-26 09:47 current -rwxrwxrwx 1 apache apache 22 2010-03-26 09:47 format -rwxrwxrwx 1 apache apache 1920 2010-03-26 09:47 fsfs.conf -rwxrwxrwx 1 apache apache 5 2010-03-26 09:47 fs-type -rwxrwxrwx 1 apache apache 2 2010-03-26 09:47 min-unpacked-rev -rwxrwxrwx 1 apache apache 4096 2010-03-26 09:47 rep-cache.db drwxrwsrwx 3 apache apache 4096 2010-03-26 09:47 revprops drwxrwsrwx 3 apache apache 4096 2010-03-26 09:47 revs drwxrwsrwx 2 apache apache 4096 2010-03-26 11:19 transactions -rwxrwxrwx 1 apache apache 2 2010-03-26 11:19 txn-current -rwxrwxrwx 1 apache apache 0 2010-03-26 09:47 txn-current-lock drwxrwsrwx 2 apache apache 4096 2010-03-26 11:19 txn-protorevs -rwxrwxrwx 1 apache apache 37 2010-03-26 09:47 uuid -rwxrwxrwx 1 apache apache 0 2010-03-26 09:47 write-lock /var/svn/repo/db/revprops: total 4 drwxrwsrwx 2 apache apache 4096 2010-03-26 09:47 0 /var/svn/repo/db/revprops/0: total 4 -rwxrwxrwx 1 apache apache 50 2010-03-26 09:47 0 /var/svn/repo/db/revs: total 4 drwxrwsrwx 2 apache apache 4096 2010-03-26 09:47 0 /var/svn/repo/db/revs/0: total 4 -rwxrwxrwx 1 apache apache 115 2010-03-26 09:47 0 /var/svn/repo/db/transactions: total 0 /var/svn/repo/db/txn-protorevs: total 0 /var/svn/repo/hooks: total 36 -rwxrwxrwx 1 apache apache 1955 2010-03-26 09:47 post-commit.tmpl -rwxrwxrwx 1 apache apache 1638 2010-03-26 09:47 post-lock.tmpl -rwxrwxrwx 1 apache apache 2267 2010-03-26 09:47 post-revprop-change.tmpl -rwxrwxrwx 1 apache apache 1567 2010-03-26 09:47 post-unlock.tmpl -rwxrwxrwx 1 apache apache 3404 2010-03-26 09:47 pre-commit.tmpl -rwxrwxrwx 1 apache apache 2410 2010-03-26 09:47 pre-lock.tmpl -rwxrwxrwx 1 apache apache 2764 2010-03-26 09:47 pre-revprop-change.tmpl -rwxrwxrwx 1 apache apache 2100 2010-03-26 09:47 pre-unlock.tmpl -rwxrwxrwx 1 apache apache 2758 2010-03-26 09:47 start-commit.tmpl /var/svn/repo/locks: total 8 -rwxrwxrwx 1 apache apache 139 2010-03-26 09:47 db.lock -rwxrwxrwx 1 apache apache 139 2010-03-26 09:47 db-logs.lock I've got httpd.conf loading svn.conf which contains: <Location /svn> DAV on DAV svn #SVNParentPath /var/svn SVNPath /var/svn/repo Authtype Basic AuthName "Subversion" AuthUserFile /var/svn/repo/svnpass Require valid-user AuthzSVNAccessFile /var/svn/repo/svnauth </Location> Full error message is: org.tigris.subversion.javahl.ClientException: RA layer request failed Server sent unexpected return value (403 Forbidden) in response to CHECKOUT request for '/svn/!svn/bln/0' Sorry for the incredibly long post, but I thought more info would be better than less. I've been fidgeting with this problem for a long time now.

    Read the article

  • xml append issue in ie,chrome

    - by 3gwebtrain
    Hi, I am creating a html page, using xml data. in which i am using the following function. It works fine with firefox,opera,safari. but in case of ie7,ie8, and chrome the data what i am getting from xml, is not appending properly. any one help me to solve this issue? in case any special thing need to concentrate on append funcation as well let me know.. $(function(){ var thisPage; var parentPage; $('ul.left-navi li a').each(function(){ $('ul.left-navi li a').removeClass('current'); var pathname = (window.location.pathname.match(/[^\/]+$/)[0]); var currentPage = $(this).attr('href'); var pathArr = new Array(); pathArr = pathname.split("."); var file = pathArr[pathArr.length - 2]; thisPage = file; if(currentPage==pathname){ $(this).addClass("active"); } }) $.get('career-utility.xml',function(myData){ var myXml = $(myData).find(thisPage); parentPage = thisPage; var overviewTitle = myXml.find('overview').attr('title'); var description = myXml.find('discription').text(); var mainsublinkTitle = myXml.find('mainsublink').attr('title'); var thisTitle = myXml.find("intro").attr('title'); var thisIntro = myXml.find("introinfo").text(); $('<h3>'+overviewTitle+'</h3>').appendTo('.overViewInfo'); $('<p>'+description+'</p>').appendTo('.overViewInfo'); var sublinks = myXml.find('mainsublink').children('sublink'); $('#intro h3').append(thisTitle); $('#intro').append(thisIntro); sublinks.each(function(numsub){ var newSubLink = $(this); var sublinkPage = $(this).attr('pageto'); var linkInfo = $(this).text(); $('ul.career-link').append('<li><a href="'+sublinkPage+'">'+linkInfo+'</a></li>'); }) $(myXml).find('listgroup').each(function(index){ var count = index; var listGroup = $(this); var listGroupTitle = $(this).attr('title'); var shortNote = $(this).attr('shortnote'); var subLink = $(this).find('sublist'); var firstList = $(this).find('list'); $('.grouplist').append('<div class="list-group"><h3>'+listGroupTitle+'</h3><ul class="level-one level' + count + '"></ul></div>'); firstList.each(function(listnum) { $(this).wrapInner('<li>') .find('sublistgroup').wrapInner('<ul>').children().unwrap() .find('sublist').wrapInner('<li>').children().unwrap(); $('ul.level'+count).append($(this).children()); }); }); }); }) Thanks for advance..

    Read the article

  • An Introduction to ASP.NET Web API

    - by Rick Strahl
    Microsoft recently released ASP.NET MVC 4.0 and .NET 4.5 and along with it, the brand spanking new ASP.NET Web API. Web API is an exciting new addition to the ASP.NET stack that provides a new, well-designed HTTP framework for creating REST and AJAX APIs (API is Microsoft’s new jargon for a service, in case you’re wondering). Although Web API ships and installs with ASP.NET MVC 4, you can use Web API functionality in any ASP.NET project, including WebForms, WebPages and MVC or just a Web API by itself. And you can also self-host Web API in your own applications from Console, Desktop or Service applications. If you're interested in a high level overview on what ASP.NET Web API is and how it fits into the ASP.NET stack you can check out my previous post: Where does ASP.NET Web API fit? In the following article, I'll focus on a practical, by example introduction to ASP.NET Web API. All the code discussed in this article is available in GitHub: https://github.com/RickStrahl/AspNetWebApiArticle [republished from my Code Magazine Article and updated for RTM release of ASP.NET Web API] Getting Started To start I’ll create a new empty ASP.NET application to demonstrate that Web API can work with any kind of ASP.NET project. Although you can create a new project based on the ASP.NET MVC/Web API template to quickly get up and running, I’ll take you through the manual setup process, because one common use case is to add Web API functionality to an existing ASP.NET application. This process describes the steps needed to hook up Web API to any ASP.NET 4.0 application. Start by creating an ASP.NET Empty Project. Then create a new folder in the project called Controllers. Add a Web API Controller Class Once you have any kind of ASP.NET project open, you can add a Web API Controller class to it. Web API Controllers are very similar to MVC Controller classes, but they work in any kind of project. Add a new item to this folder by using the Add New Item option in Visual Studio and choose Web API Controller Class, as shown in Figure 1. Figure 1: This is how you create a new Controller Class in Visual Studio   Make sure that the name of the controller class includes Controller at the end of it, which is required in order for Web API routing to find it. Here, the name for the class is AlbumApiController. For this example, I’ll use a Music Album model to demonstrate basic behavior of Web API. The model consists of albums and related songs where an album has properties like Name, Artist and YearReleased and a list of songs with a SongName and SongLength as well as an AlbumId that links it to the album. You can find the code for the model (and the rest of these samples) on Github. To add the file manually, create a new folder called Model, and add a new class Album.cs and copy the code into it. There’s a static AlbumData class with a static CreateSampleAlbumData() method that creates a short list of albums on a static .Current that I’ll use for the examples. Before we look at what goes into the controller class though, let’s hook up routing so we can access this new controller. Hooking up Routing in Global.asax To start, I need to perform the one required configuration task in order for Web API to work: I need to configure routing to the controller. Like MVC, Web API uses routing to provide clean, extension-less URLs to controller methods. Using an extension method to ASP.NET’s static RouteTable class, you can use the MapHttpRoute() (in the System.Web.Http namespace) method to hook-up the routing during Application_Start in global.asax.cs shown in Listing 1.using System; using System.Web.Routing; using System.Web.Http; namespace AspNetWebApi { public class Global : System.Web.HttpApplication { protected void Application_Start(object sender, EventArgs e) { RouteTable.Routes.MapHttpRoute( name: "AlbumVerbs", routeTemplate: "albums/{title}", defaults: new { symbol = RouteParameter.Optional, controller="AlbumApi" } ); } } } This route configures Web API to direct URLs that start with an albums folder to the AlbumApiController class. Routing in ASP.NET is used to create extensionless URLs and allows you to map segments of the URL to specific Route Value parameters. A route parameter, with a name inside curly brackets like {name}, is mapped to parameters on the controller methods. Route parameters can be optional, and there are two special route parameters – controller and action – that determine the controller to call and the method to activate respectively. HTTP Verb Routing Routing in Web API can route requests by HTTP Verb in addition to standard {controller},{action} routing. For the first examples, I use HTTP Verb routing, as shown Listing 1. Notice that the route I’ve defined does not include an {action} route value or action value in the defaults. Rather, Web API can use the HTTP Verb in this route to determine the method to call the controller, and a GET request maps to any method that starts with Get. So methods called Get() or GetAlbums() are matched by a GET request and a POST request maps to a Post() or PostAlbum(). Web API matches a method by name and parameter signature to match a route, query string or POST values. In lieu of the method name, the [HttpGet,HttpPost,HttpPut,HttpDelete, etc] attributes can also be used to designate the accepted verbs explicitly if you don’t want to follow the verb naming conventions. Although HTTP Verb routing is a good practice for REST style resource APIs, it’s not required and you can still use more traditional routes with an explicit {action} route parameter. When {action} is supplied, the HTTP verb routing is ignored. I’ll talk more about alternate routes later. When you’re finished with initial creation of files, your project should look like Figure 2.   Figure 2: The initial project has the new API Controller Album model   Creating a small Album Model Now it’s time to create some controller methods to serve data. For these examples, I’ll use a very simple Album and Songs model to play with, as shown in Listing 2. public class Song { public string AlbumId { get; set; } [Required, StringLength(80)] public string SongName { get; set; } [StringLength(5)] public string SongLength { get; set; } } public class Album { public string Id { get; set; } [Required, StringLength(80)] public string AlbumName { get; set; } [StringLength(80)] public string Artist { get; set; } public int YearReleased { get; set; } public DateTime Entered { get; set; } [StringLength(150)] public string AlbumImageUrl { get; set; } [StringLength(200)] public string AmazonUrl { get; set; } public virtual List<Song> Songs { get; set; } public Album() { Songs = new List<Song>(); Entered = DateTime.Now; // Poor man's unique Id off GUID hash Id = Guid.NewGuid().GetHashCode().ToString("x"); } public void AddSong(string songName, string songLength = null) { this.Songs.Add(new Song() { AlbumId = this.Id, SongName = songName, SongLength = songLength }); } } Once the model has been created, I also added an AlbumData class that generates some static data in memory that is loaded onto a static .Current member. The signature of this class looks like this and that's what I'll access to retrieve the base data:public static class AlbumData { // sample data - static list public static List<Album> Current = CreateSampleAlbumData(); /// <summary> /// Create some sample data /// </summary> /// <returns></returns> public static List<Album> CreateSampleAlbumData() { … }} You can check out the full code for the data generation online. Creating an AlbumApiController Web API shares many concepts of ASP.NET MVC, and the implementation of your API logic is done by implementing a subclass of the System.Web.Http.ApiController class. Each public method in the implemented controller is a potential endpoint for the HTTP API, as long as a matching route can be found to invoke it. The class name you create should end in Controller, which is how Web API matches the controller route value to figure out which class to invoke. Inside the controller you can implement methods that take standard .NET input parameters and return .NET values as results. Web API’s binding tries to match POST data, route values, form values or query string values to your parameters. Because the controller is configured for HTTP Verb based routing (no {action} parameter in the route), any methods that start with Getxxxx() are called by an HTTP GET operation. You can have multiple methods that match each HTTP Verb as long as the parameter signatures are different and can be matched by Web API. In Listing 3, I create an AlbumApiController with two methods to retrieve a list of albums and a single album by its title .public class AlbumApiController : ApiController { public IEnumerable<Album> GetAlbums() { var albums = AlbumData.Current.OrderBy(alb => alb.Artist); return albums; } public Album GetAlbum(string title) { var album = AlbumData.Current .SingleOrDefault(alb => alb.AlbumName.Contains(title)); return album; }} To access the first two requests, you can use the following URLs in your browser: http://localhost/aspnetWebApi/albumshttp://localhost/aspnetWebApi/albums/Dirty%20Deeds Note that you’re not specifying the actions of GetAlbum or GetAlbums in these URLs. Instead Web API’s routing uses HTTP GET verb to route to these methods that start with Getxxx() with the first mapping to the parameterless GetAlbums() method and the latter to the GetAlbum(title) method that receives the title parameter mapped as optional in the route. Content Negotiation When you access any of the URLs above from a browser, you get either an XML or JSON result returned back. The album list result for Chrome 17 and Internet Explorer 9 is shown Figure 3. Figure 3: Web API responses can vary depending on the browser used, demonstrating Content Negotiation in action as these two browsers send different HTTP Accept headers.   Notice that the results are not the same: Chrome returns an XML response and IE9 returns a JSON response. Whoa, what’s going on here? Shouldn’t we see the same result in both browsers? Actually, no. Web API determines what type of content to return based on Accept headers. HTTP clients, like browsers, use Accept headers to specify what kind of content they’d like to see returned. Browsers generally ask for HTML first, followed by a few additional content types. Chrome (and most other major browsers) ask for: Accept: text/html, application/xhtml+xml,application/xml; q=0.9,*/*;q=0.8 IE9 asks for: Accept: text/html, application/xhtml+xml, */* Note that Chrome’s Accept header includes application/xml, which Web API finds in its list of supported media types and returns an XML response. IE9 does not include an Accept header type that works on Web API by default, and so it returns the default format, which is JSON. This is an important and very useful feature that was missing from any previous Microsoft REST tools: Web API automatically switches output formats based on HTTP Accept headers. Nowhere in the server code above do you have to explicitly specify the output format. Rather, Web API determines what format the client is requesting based on the Accept headers and automatically returns the result based on the available formatters. This means that a single method can handle both XML and JSON results.. Using this simple approach makes it very easy to create a single controller method that can return JSON, XML, ATOM or even OData feeds by providing the appropriate Accept header from the client. By default you don’t have to worry about the output format in your code. Note that you can still specify an explicit output format if you choose, either globally by overriding the installed formatters, or individually by returning a lower level HttpResponseMessage instance and setting the formatter explicitly. More on that in a minute. Along the same lines, any content sent to the server via POST/PUT is parsed by Web API based on the HTTP Content-type of the data sent. The same formats allowed for output are also allowed on input. Again, you don’t have to do anything in your code – Web API automatically performs the deserialization from the content. Accessing Web API JSON Data with jQuery A very common scenario for Web API endpoints is to retrieve data for AJAX calls from the Web browser. Because JSON is the default format for Web API, it’s easy to access data from the server using jQuery and its getJSON() method. This example receives the albums array from GetAlbums() and databinds it into the page using knockout.js.$.getJSON("albums/", function (albums) { // make knockout template visible $(".album").show(); // create view object and attach array var view = { albums: albums }; ko.applyBindings(view); }); Figure 4 shows this and the next example’s HTML output. You can check out the complete HTML and script code at http://goo.gl/Ix33C (.html) and http://goo.gl/tETlg (.js). Figu Figure 4: The Album Display sample uses JSON data loaded from Web API.   The result from the getJSON() call is a JavaScript object of the server result, which comes back as a JavaScript array. In the code, I use knockout.js to bind this array into the UI, which as you can see, requires very little code, instead using knockout’s data-bind attributes to bind server data to the UI. Of course, this is just one way to use the data – it’s entirely up to you to decide what to do with the data in your client code. Along the same lines, I can retrieve a single album to display when the user clicks on an album. The response returns the album information and a child array with all the songs. The code to do this is very similar to the last example where we pulled the albums array:$(".albumlink").live("click", function () { var id = $(this).data("id"); // title $.getJSON("albums/" + id, function (album) { ko.applyBindings(album, $("#divAlbumDialog")[0]); $("#divAlbumDialog").show(); }); }); Here the URL looks like this: /albums/Dirty%20Deeds, where the title is the ID captured from the clicked element’s data ID attribute. Explicitly Overriding Output Format When Web API automatically converts output using content negotiation, it does so by matching Accept header media types to the GlobalConfiguration.Configuration.Formatters and the SupportedMediaTypes of each individual formatter. You can add and remove formatters to globally affect what formats are available and it’s easy to create and plug in custom formatters.The example project includes a JSONP formatter that can be plugged in to provide JSONP support for requests that have a callback= querystring parameter. Adding, removing or replacing formatters is a global option you can use to manipulate content. It’s beyond the scope of this introduction to show how it works, but you can review the sample code or check out my blog entry on the subject (http://goo.gl/UAzaR). If automatic processing is not desirable in a particular Controller method, you can override the response output explicitly by returning an HttpResponseMessage instance. HttpResponseMessage is similar to ActionResult in ASP.NET MVC in that it’s a common way to return an abstract result message that contains content. HttpResponseMessage s parsed by the Web API framework using standard interfaces to retrieve the response data, status code, headers and so on[MS2] . Web API turns every response – including those Controller methods that return static results – into HttpResponseMessage instances. Explicitly returning an HttpResponseMessage instance gives you full control over the output and lets you mostly bypass WebAPI’s post-processing of the HTTP response on your behalf. HttpResponseMessage allows you to customize the response in great detail. Web API’s attention to detail in the HTTP spec really shows; many HTTP options are exposed as properties and enumerations with detailed IntelliSense comments. Even if you’re new to building REST-based interfaces, the API guides you in the right direction for returning valid responses and response codes. For example, assume that I always want to return JSON from the GetAlbums() controller method and ignore the default media type content negotiation. To do this, I can adjust the output format and headers as shown in Listing 4.public HttpResponseMessage GetAlbums() { var albums = AlbumData.Current.OrderBy(alb => alb.Artist); // Create a new HttpResponse with Json Formatter explicitly var resp = new HttpResponseMessage(HttpStatusCode.OK); resp.Content = new ObjectContent<IEnumerable<Album>>( albums, new JsonMediaTypeFormatter()); // Get Default Formatter based on Content Negotiation //var resp = Request.CreateResponse<IEnumerable<Album>>(HttpStatusCode.OK, albums); resp.Headers.ConnectionClose = true; resp.Headers.CacheControl = new CacheControlHeaderValue(); resp.Headers.CacheControl.Public = true; return resp; } This example returns the same IEnumerable<Album> value, but it wraps the response into an HttpResponseMessage so you can control the entire HTTP message result including the headers, formatter and status code. In Listing 4, I explicitly specify the formatter using the JsonMediaTypeFormatter to always force the content to JSON.  If you prefer to use the default content negotiation with HttpResponseMessage results, you can create the Response instance using the Request.CreateResponse method:var resp = Request.CreateResponse<IEnumerable<Album>>(HttpStatusCode.OK, albums); This provides you an HttpResponse object that's pre-configured with the default formatter based on Content Negotiation. Once you have an HttpResponse object you can easily control most HTTP aspects on this object. What's sweet here is that there are many more detailed properties on HttpResponse than the core ASP.NET Response object, with most options being explicitly configurable with enumerations that make it easy to pick the right headers and response codes from a list of valid codes. It makes HTTP features available much more discoverable even for non-hardcore REST/HTTP geeks. Non-Serialized Results The output returned doesn’t have to be a serialized value but can also be raw data, like strings, binary data or streams. You can use the HttpResponseMessage.Content object to set a number of common Content classes. Listing 5 shows how to return a binary image using the ByteArrayContent class from a Controller method. [HttpGet] public HttpResponseMessage AlbumArt(string title) { var album = AlbumData.Current.FirstOrDefault(abl => abl.AlbumName.StartsWith(title)); if (album == null) { var resp = Request.CreateResponse<ApiMessageError>( HttpStatusCode.NotFound, new ApiMessageError("Album not found")); return resp; } // kinda silly - we would normally serve this directly // but hey - it's a demo. var http = new WebClient(); var imageData = http.DownloadData(album.AlbumImageUrl); // create response and return var result = new HttpResponseMessage(HttpStatusCode.OK); result.Content = new ByteArrayContent(imageData); result.Content.Headers.ContentType = new MediaTypeHeaderValue("image/jpeg"); return result; } The image retrieval from Amazon is contrived, but it shows how to return binary data using ByteArrayContent. It also demonstrates that you can easily return multiple types of content from a single controller method, which is actually quite common. If an error occurs - such as a resource can’t be found or a validation error – you can return an error response to the client that’s very specific to the error. In GetAlbumArt(), if the album can’t be found, we want to return a 404 Not Found status (and realistically no error, as it’s an image). Note that if you are not using HTTP Verb-based routing or not accessing a method that starts with Get/Post etc., you have to specify one or more HTTP Verb attributes on the method explicitly. Here, I used the [HttpGet] attribute to serve the image. Another option to handle the error could be to return a fixed placeholder image if no album could be matched or the album doesn’t have an image. When returning an error code, you can also return a strongly typed response to the client. For example, you can set the 404 status code and also return a custom error object (ApiMessageError is a class I defined) like this:return Request.CreateResponse<ApiMessageError>( HttpStatusCode.NotFound, new ApiMessageError("Album not found") );   If the album can be found, the image will be returned. The image is downloaded into a byte[] array, and then assigned to the result’s Content property. I created a new ByteArrayContent instance and assigned the image’s bytes and the content type so that it displays properly in the browser. There are other content classes available: StringContent, StreamContent, ByteArrayContent, MultipartContent, and ObjectContent are at your disposal to return just about any kind of content. You can create your own Content classes if you frequently return custom types and handle the default formatter assignments that should be used to send the data out . Although HttpResponseMessage results require more code than returning a plain .NET value from a method, it allows much more control over the actual HTTP processing than automatic processing. It also makes it much easier to test your controller methods as you get a response object that you can check for specific status codes and output messages rather than just a result value. Routing Again Ok, let’s get back to the image example. Using the original routing we have setup using HTTP Verb routing there's no good way to serve the image. In order to return my album art image I’d like to use a URL like this: http://localhost/aspnetWebApi/albums/Dirty%20Deeds/image In order to create a URL like this, I have to create a new Controller because my earlier routes pointed to the AlbumApiController using HTTP Verb routing. HTTP Verb based routing is great for representing a single set of resources such as albums. You can map operations like add, delete, update and read easily using HTTP Verbs. But you cannot mix action based routing into a an HTTP Verb routing controller - you can only map HTTP Verbs and each method has to be unique based on parameter signature. You can't have multiple GET operations to methods with the same signature. So GetImage(string id) and GetAlbum(string title) are in conflict in an HTTP GET routing scenario. In fact, I was unable to make the above Image URL work with any combination of HTTP Verb plus Custom routing using the single Albums controller. There are number of ways around this, but all involve additional controllers.  Personally, I think it’s easier to use explicit Action routing and then add custom routes if you need to simplify your URLs further. So in order to accommodate some of the other examples, I created another controller – AlbumRpcApiController – to handle all requests that are explicitly routed via actions (/albums/rpc/AlbumArt) or are custom routed with explicit routes defined in the HttpConfiguration. I added the AlbumArt() method to this new AlbumRpcApiController class. For the image URL to work with the new AlbumRpcApiController, you need a custom route placed before the default route from Listing 1.RouteTable.Routes.MapHttpRoute( name: "AlbumRpcApiAction", routeTemplate: "albums/rpc/{action}/{title}", defaults: new { title = RouteParameter.Optional, controller = "AlbumRpcApi", action = "GetAblums" } ); Now I can use either of the following URLs to access the image: Custom route: (/albums/rpc/{title}/image)http://localhost/aspnetWebApi/albums/PowerAge/image Action route: (/albums/rpc/action/{title})http://localhost/aspnetWebAPI/albums/rpc/albumart/PowerAge Sending Data to the Server To send data to the server and add a new album, you can use an HTTP POST operation. Since I’m using HTTP Verb-based routing in the original AlbumApiController, I can implement a method called PostAlbum()to accept a new album from the client. Listing 6 shows the Web API code to add a new album.public HttpResponseMessage PostAlbum(Album album) { if (!this.ModelState.IsValid) { // my custom error class var error = new ApiMessageError() { message = "Model is invalid" }; // add errors into our client error model for client foreach (var prop in ModelState.Values) { var modelError = prop.Errors.FirstOrDefault(); if (!string.IsNullOrEmpty(modelError.ErrorMessage)) error.errors.Add(modelError.ErrorMessage); else error.errors.Add(modelError.Exception.Message); } return Request.CreateResponse<ApiMessageError>(HttpStatusCode.Conflict, error); } // update song id which isn't provided foreach (var song in album.Songs) song.AlbumId = album.Id; // see if album exists already var matchedAlbum = AlbumData.Current .SingleOrDefault(alb => alb.Id == album.Id || alb.AlbumName == album.AlbumName); if (matchedAlbum == null) AlbumData.Current.Add(album); else matchedAlbum = album; // return a string to show that the value got here var resp = Request.CreateResponse(HttpStatusCode.OK, string.Empty); resp.Content = new StringContent(album.AlbumName + " " + album.Entered.ToString(), Encoding.UTF8, "text/plain"); return resp; } The PostAlbum() method receives an album parameter, which is automatically deserialized from the POST buffer the client sent. The data passed from the client can be either XML or JSON. Web API automatically figures out what format it needs to deserialize based on the content type and binds the content to the album object. Web API uses model binding to bind the request content to the parameter(s) of controller methods. Like MVC you can check the model by looking at ModelState.IsValid. If it’s not valid, you can run through the ModelState.Values collection and check each binding for errors. Here I collect the error messages into a string array that gets passed back to the client via the result ApiErrorMessage object. When a binding error occurs, you’ll want to return an HTTP error response and it’s best to do that with an HttpResponseMessage result. In Listing 6, I used a custom error class that holds a message and an array of detailed error messages for each binding error. I used this object as the content to return to the client along with my Conflict HTTP Status Code response. If binding succeeds, the example returns a string with the name and date entered to demonstrate that you captured the data. Normally, a method like this should return a Boolean or no response at all (HttpStatusCode.NoConent). The sample uses a simple static list to hold albums, so once you’ve added the album using the Post operation, you can hit the /albums/ URL to see that the new album was added. The client jQuery code to call the POST operation from the client with jQuery is shown in Listing 7. var id = new Date().getTime().toString(); var album = { "Id": id, "AlbumName": "Power Age", "Artist": "AC/DC", "YearReleased": 1977, "Entered": "2002-03-11T18:24:43.5580794-10:00", "AlbumImageUrl": http://ecx.images-amazon.com/images/…, "AmazonUrl": http://www.amazon.com/…, "Songs": [ { "SongName": "Rock 'n Roll Damnation", "SongLength": 3.12}, { "SongName": "Downpayment Blues", "SongLength": 4.22 }, { "SongName": "Riff Raff", "SongLength": 2.42 } ] } $.ajax( { url: "albums/", type: "POST", contentType: "application/json", data: JSON.stringify(album), processData: false, beforeSend: function (xhr) { // not required since JSON is default output xhr.setRequestHeader("Accept", "application/json"); }, success: function (result) { // reload list of albums page.loadAlbums(); }, error: function (xhr, status, p3, p4) { var err = "Error"; if (xhr.responseText && xhr.responseText[0] == "{") err = JSON.parse(xhr.responseText).message; alert(err); } }); The code in Listing 7 creates an album object in JavaScript to match the structure of the .NET Album class. This object is passed to the $.ajax() function to send to the server as POST. The data is turned into JSON and the content type set to application/json so that the server knows what to convert when deserializing in the Album instance. The jQuery code hooks up success and failure events. Success returns the result data, which is a string that’s echoed back with an alert box. If an error occurs, jQuery returns the XHR instance and status code. You can check the XHR to see if a JSON object is embedded and if it is, you can extract it by de-serializing it and accessing the .message property. REST standards suggest that updates to existing resources should use PUT operations. REST standards aside, I’m not a big fan of separating out inserts and updates so I tend to have a single method that handles both. But if you want to follow REST suggestions, you can create a PUT method that handles updates by forwarding the PUT operation to the POST method:public HttpResponseMessage PutAlbum(Album album) { return PostAlbum(album); } To make the corresponding $.ajax() call, all you have to change from Listing 7 is the type: from POST to PUT. Model Binding with UrlEncoded POST Variables In the example in Listing 7 I used JSON objects to post a serialized object to a server method that accepted an strongly typed object with the same structure, which is a common way to send data to the server. However, Web API supports a number of different ways that data can be received by server methods. For example, another common way is to use plain UrlEncoded POST  values to send to the server. Web API supports Model Binding that works similar (but not the same) as MVC's model binding where POST variables are mapped to properties of object parameters of the target method. This is actually quite common for AJAX calls that want to avoid serialization and the potential requirement of a JSON parser on older browsers. For example, using jQUery you might use the $.post() method to send a new album to the server (albeit one without songs) using code like the following:$.post("albums/",{AlbumName: "Dirty Deeds", YearReleased: 1976 … },albumPostCallback); Although the code looks very similar to the client code we used before passing JSON, here the data passed is URL encoded values (AlbumName=Dirty+Deeds&YearReleased=1976 etc.). Web API then takes this POST data and maps each of the POST values to the properties of the Album object in the method's parameter. Although the client code is different the server can both handle the JSON object, or the UrlEncoded POST values. Dynamic Access to POST Data There are also a few options available to dynamically access POST data, if you know what type of data you're dealing with. If you have POST UrlEncoded values, you can dynamically using a FormsDataCollection:[HttpPost] public string PostAlbum(FormDataCollection form) { return string.Format("{0} - released {1}", form.Get("AlbumName"),form.Get("RearReleased")); } The FormDataCollection is a very simple object, that essentially provides the same functionality as Request.Form[] in ASP.NET. Request.Form[] still works if you're running hosted in an ASP.NET application. However as a general rule, while ASP.NET's functionality is always available when running Web API hosted inside of an  ASP.NET application, using the built in classes specific to Web API makes it possible to run Web API applications in a self hosted environment outside of ASP.NET. If your client is sending JSON to your server, and you don't want to map the JSON to a strongly typed object because you only want to retrieve a few simple values, you can also accept a JObject parameter in your API methods:[HttpPost] public string PostAlbum(JObject jsonData) { dynamic json = jsonData; JObject jalbum = json.Album; JObject juser = json.User; string token = json.UserToken; var album = jalbum.ToObject<Album>(); var user = juser.ToObject<User>(); return String.Format("{0} {1} {2}", album.AlbumName, user.Name, token); } There quite a few options available to you to receive data with Web API, which gives you more choices for the right tool for the job. Unfortunately one shortcoming of Web API is that POST data is always mapped to a single parameter. This means you can't pass multiple POST parameters to methods that receive POST data. It's possible to accept multiple parameters, but only one can map to the POST content - the others have to come from the query string or route values. I have a couple of Blog POSTs that explain what works and what doesn't here: Passing multiple POST parameters to Web API Controller Methods Mapping UrlEncoded POST Values in ASP.NET Web API   Handling Delete Operations Finally, to round out the server API code of the album example we've been discussin, here’s the DELETE verb controller method that allows removal of an album by its title:public HttpResponseMessage DeleteAlbum(string title) { var matchedAlbum = AlbumData.Current.Where(alb => alb.AlbumName == title) .SingleOrDefault(); if (matchedAlbum == null) return new HttpResponseMessage(HttpStatusCode.NotFound); AlbumData.Current.Remove(matchedAlbum); return new HttpResponseMessage(HttpStatusCode.NoContent); } To call this action method using jQuery, you can use:$(".removeimage").live("click", function () { var $el = $(this).parent(".album"); var txt = $el.find("a").text(); $.ajax({ url: "albums/" + encodeURIComponent(txt), type: "Delete", success: function (result) { $el.fadeOut().remove(); }, error: jqError }); }   Note the use of the DELETE verb in the $.ajax() call, which routes to DeleteAlbum on the server. DELETE is a non-content operation, so you supply a resource ID (the title) via route value or the querystring. Routing Conflicts In all requests with the exception of the AlbumArt image example shown so far, I used HTTP Verb routing that I set up in Listing 1. HTTP Verb Routing is a recommendation that is in line with typical REST access to HTTP resources. However, it takes quite a bit of effort to create REST-compliant API implementations based only on HTTP Verb routing only. You saw one example that didn’t really fit – the return of an image where I created a custom route albums/{title}/image that required creation of a second controller and a custom route to work. HTTP Verb routing to a controller does not mix with custom or action routing to the same controller because of the limited mapping of HTTP verbs imposed by HTTP Verb routing. To understand some of the problems with verb routing, let’s look at another example. Let’s say you create a GetSortableAlbums() method like this and add it to the original AlbumApiController accessed via HTTP Verb routing:[HttpGet] public IQueryable<Album> SortableAlbums() { var albums = AlbumData.Current; // generally should be done only on actual queryable results (EF etc.) // Done here because we're running with a static list but otherwise might be slow return albums.AsQueryable(); } If you compile this code and try to now access the /albums/ link, you get an error: Multiple Actions were found that match the request. HTTP Verb routing only allows access to one GET operation per parameter/route value match. If more than one method exists with the same parameter signature, it doesn’t work. As I mentioned earlier for the image display, the only solution to get this method to work is to throw it into another controller. Because I already set up the AlbumRpcApiController I can add the method there. First, I should rename the method to SortableAlbums() so I’m not using a Get prefix for the method. This also makes the action parameter look cleaner in the URL - it looks less like a method and more like a noun. I can then create a new route that handles direct-action mapping:RouteTable.Routes.MapHttpRoute( name: "AlbumRpcApiAction", routeTemplate: "albums/rpc/{action}/{title}", defaults: new { title = RouteParameter.Optional, controller = "AlbumRpcApi", action = "GetAblums" } ); As I am explicitly adding a route segment – rpc – into the route template, I can now reference explicit methods in the Web API controller using URLs like this: http://localhost/AspNetWebApi/rpc/SortableAlbums Error Handling I’ve already done some minimal error handling in the examples. For example in Listing 6, I detected some known-error scenarios like model validation failing or a resource not being found and returning an appropriate HttpResponseMessage result. But what happens if your code just blows up or causes an exception? If you have a controller method, like this:[HttpGet] public void ThrowException() { throw new UnauthorizedAccessException("Unauthorized Access Sucka"); } You can call it with this: http://localhost/AspNetWebApi/albums/rpc/ThrowException The default exception handling displays a 500-status response with the serialized exception on the local computer only. When you connect from a remote computer, Web API throws back a 500  HTTP Error with no data returned (IIS then adds its HTML error page). The behavior is configurable in the GlobalConfiguration:GlobalConfiguration .Configuration .IncludeErrorDetailPolicy = IncludeErrorDetailPolicy.Never; If you want more control over your error responses sent from code, you can throw explicit error responses yourself using HttpResponseException. When you throw an HttpResponseException the response parameter is used to generate the output for the Controller action. [HttpGet] public void ThrowError() { var resp = Request.CreateResponse<ApiMessageError>( HttpStatusCode.BadRequest, new ApiMessageError("Your code stinks!")); throw new HttpResponseException(resp); } Throwing an HttpResponseException stops the processing of the controller method and immediately returns the response you passed to the exception. Unlike other Exceptions fired inside of WebAPI, HttpResponseException bypasses the Exception Filters installed and instead just outputs the response you provide. In this case, the serialized ApiMessageError result string is returned in the default serialization format – XML or JSON. You can pass any content to HttpResponseMessage, which includes creating your own exception objects and consistently returning error messages to the client. Here’s a small helper method on the controller that you might use to send exception info back to the client consistently:private void ThrowSafeException(string message, HttpStatusCode statusCode = HttpStatusCode.BadRequest) { var errResponse = Request.CreateResponse<ApiMessageError>(statusCode, new ApiMessageError() { message = message }); throw new HttpResponseException(errResponse); } You can then use it to output any captured errors from code:[HttpGet] public void ThrowErrorSafe() { try { List<string> list = null; list.Add("Rick"); } catch (Exception ex) { ThrowSafeException(ex.Message); } }   Exception Filters Another more global solution is to create an Exception Filter. Filters in Web API provide the ability to pre- and post-process controller method operations. An exception filter looks at all exceptions fired and then optionally creates an HttpResponseMessage result. Listing 8 shows an example of a basic Exception filter implementation.public class UnhandledExceptionFilter : ExceptionFilterAttribute { public override void OnException(HttpActionExecutedContext context) { HttpStatusCode status = HttpStatusCode.InternalServerError; var exType = context.Exception.GetType(); if (exType == typeof(UnauthorizedAccessException)) status = HttpStatusCode.Unauthorized; else if (exType == typeof(ArgumentException)) status = HttpStatusCode.NotFound; var apiError = new ApiMessageError() { message = context.Exception.Message }; // create a new response and attach our ApiError object // which now gets returned on ANY exception result var errorResponse = context.Request.CreateResponse<ApiMessageError>(status, apiError); context.Response = errorResponse; base.OnException(context); } } Exception Filter Attributes can be assigned to an ApiController class like this:[UnhandledExceptionFilter] public class AlbumRpcApiController : ApiController or you can globally assign it to all controllers by adding it to the HTTP Configuration's Filters collection:GlobalConfiguration.Configuration.Filters.Add(new UnhandledExceptionFilter()); The latter is a great way to get global error trapping so that all errors (short of hard IIS errors and explicit HttpResponseException errors) return a valid error response that includes error information in the form of a known-error object. Using a filter like this allows you to throw an exception as you normally would and have your filter create a response in the appropriate output format that the client expects. For example, an AJAX application can on failure expect to see a JSON error result that corresponds to the real error that occurred rather than a 500 error along with HTML error page that IIS throws up. You can even create some custom exceptions so you can differentiate your own exceptions from unhandled system exceptions - you often don't want to display error information from 'unknown' exceptions as they may contain sensitive system information or info that's not generally useful to users of your application/site. This is just one example of how ASP.NET Web API is configurable and extensible. Exception filters are just one example of how you can plug-in into the Web API request flow to modify output. Many more hooks exist and I’ll take a closer look at extensibility in Part 2 of this article in the future. Summary Web API is a big improvement over previous Microsoft REST and AJAX toolkits. The key features to its usefulness are its ease of use with simple controller based logic, familiar MVC-style routing, low configuration impact, extensibility at all levels and tight attention to exposing and making HTTP semantics easily discoverable and easy to use. Although none of the concepts used in Web API are new or radical, Web API combines the best of previous platforms into a single framework that’s highly functional, easy to work with, and extensible to boot. I think that Microsoft has hit a home run with Web API. Related Resources Where does ASP.NET Web API fit? Sample Source Code on GitHub Passing multiple POST parameters to Web API Controller Methods Mapping UrlEncoded POST Values in ASP.NET Web API Creating a JSONP Formatter for ASP.NET Web API Removing the XML Formatter from ASP.NET Web API Applications© Rick Strahl, West Wind Technologies, 2005-2012Posted in Web Api   Tweet !function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0];if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src="//platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs);}}(document,"script","twitter-wjs"); (function() { var po = document.createElement('script'); po.type = 'text/javascript'; po.async = true; po.src = 'https://apis.google.com/js/plusone.js'; var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(po, s); })();

    Read the article

  • Ubuntu - why would /var/log/dmesg stop updating after boot? does not show panic/cpu_hung errors which the console shows

    - by Tom G
    So I have an Ubuntu 10.04 install VM on a host. Latest 2.6.38-15-server kernel . /var/log/dmesg displays only the bootup but will stop recording after that. It will not show the trace/cpu_hung errors I am trying to troubleshoot. /var/log/dmesg.0 , dmesg.1 nothing - I did a string search for the text that displays on the console during the crash and NOTHING gets logged anywhere in /var/log/* . I have to call into the provider and ask them to take a screenshot of the console since nothing shows in dmesg. Why would /var/log/dmesg not record kernel panics, or such?

    Read the article

  • Why are my files in /var/lock and where did they just go?!

    - by Nicky Hajal
    I am hosting a website on Debian 5.0 & Apache2. Today one of my websites was down, Apache said it couldn't find the directory. I located the files and the whole site once in /var/www/site was now /var/lock/site. All the files were present. I was confused, but figured I'd just move it back. mv /var/lock/site /var/www All looked fine... Except that only the directories moved and the files appear to be lost! I am working on restoring from backups but I would really love to know what happened and where my files went (the backups are a few days old). Thanks for your help!

    Read the article

  • How to change suexec root directory from "/var/www" to "/home"?

    - by Oudin
    Hi I've installed suexec using on ubuntu 12.04: apt-get install apache2 apache2-suexec libapache2-mod-fcgid php5-cgi However when I run the following command: sudo /usr/lib/apache2/suexec -V I get the following info: -D AP_DOC_ROOT="/var/www" -D AP_GID_MIN=100 -D AP_HTTPD_USER="www-data" -D AP_LOG_EXEC="/var/log/apache2/suexec.log" -D AP_SAFE_PATH="/usr/local/bin:/usr/bin:/bin" -D AP_UID_MIN=100 -D AP_USERDIR_SUFFIX="public_html" I'm utilizing "/home/user/public_html" to serve users content on the web not "/var/www" How can I change the root directory to "/home"?

    Read the article

  • Smooth animation on a persistently refreshing canvas

    - by Neurofluxation
    Yo everyone! I have been working on an Isometric Tile Game Engine in HTML5/Canvas for a little while now and I have a complete working game. Earlier today I looked back over my code and thought: "hmm, let's try to get this animated smoothly..." And since then, that is all I have tried to do. The problem I would like the character to actually "slide" from tile to tile - but the canvas redrawing doesn't allow this - does anyone have any ideas....? Code and fiddle below... Fiddle with it! http://jsfiddle.net/neuroflux/n7VAu/ <html> <head> <title>tileEngine - Isometric</title> <style type="text/css"> * { margin: 0px; padding: 0px; font-family: arial, helvetica, sans-serif; font-size: 12px; cursor: default; } </style> <script type="text/javascript"> var map = Array( //land [[0,0,0],[0,0,0],[0,0,0],[0,0,0],[0,0,0],[0,0,0],[0,0,0],[0,0,0],[0,0,0],[0,0,0]], [[0,0,0],[0,0,0],[0,0,0],[0,0,0],[0,0,0],[0,0,0],[0,0,0],[0,0,0],[0,0,0],[0,0,0]], [[0,0,0],[0,0,0],[0,0,0],[0,0,0],[0,0,0],[0,0,0],[0,0,0],[0,0,0],[0,0,0],[0,0,0]], [[0,0,0],[0,0,0],[0,0,0],[0,0,0],[0,0,0],[0,0,0],[0,0,0],[0,0,0],[0,0,0],[0,0,0]], [[0,0,0],[0,0,0],[0,0,0],[0,0,0],[0,0,0],[0,0,0],[0,0,0],[0,0,0],[0,0,0],[0,0,0]], [[0,0,0],[0,0,0],[0,0,0],[0,0,0],[0,0,0],[0,0,0],[0,0,0],[0,0,0],[0,0,0],[0,0,0]], [[0,0,0],[0,0,0],[0,0,0],[0,0,0],[0,0,0],[0,0,0],[0,0,0],[0,0,0],[0,0,0],[0,0,0]], [[0,0,0],[0,0,0],[0,0,0],[0,0,0],[0,0,0],[0,0,0],[0,0,0],[0,0,0],[0,0,0],[0,0,0]], [[0,0,0],[0,0,0],[0,0,0],[0,0,0],[0,0,0],[0,0,0],[0,0,0],[0,0,0],[0,0,0],[0,0,0]], [[0,0,0],[0,0,0],[0,0,0],[0,0,0],[0,0,0],[0,0,0],[0,0,0],[0,0,0],[0,0,0],[0,0,0]] ); var tileDict = Array("http://www.wikiword.co.uk/release-candidate/canvas/tileEngine/land.png"); var charDict = Array("http://www.wikiword.co.uk/release-candidate/canvas/tileEngine/mario.png"); var objectDict = Array("http://www.wikiword.co.uk/release-candidate/canvas/tileEngine/rock.png"); //last is one more var objectImg = new Array(); var charImg = new Array(); var tileImg = new Array(); var loaded = 0; var loadTimer; var ymouse; var xmouse; var eventUpdate = 0; var playerX = 0; var playerY = 0; function loadImg(){ //preload images and calculate the total loading time for(var i=0;i<tileDict.length;i++){ tileImg[i] = new Image(); tileImg[i].src = tileDict[i]; tileImg[i].onload = function(){ loaded++; } } i = 0; for(var i=0;i<charDict.length;i++){ charImg[i] = new Image(); charImg[i].src = charDict[i]; charImg[i].onload = function(){ loaded++; } } i = 0; for(var i=0;i<objectDict.length;i++){ objectImg[i] = new Image(); objectImg[i].src = objectDict[i]; objectImg[i].onload = function(){ loaded++; } } } function checkKeycode(event) { //key pressed var keycode; if(event == null) { keyCode = window.event.keyCode; } else { keyCode = event.keyCode; } switch(keyCode) { case 38: //left if(!map[playerX-1][playerY][1] > 0){ playerX--; } break; case 40: //right if(!map[playerX+1][playerY][1] > 0){ playerX++; } break; case 39: //up if(!map[playerX][playerY-1][1] > 0){ playerY--; } break; case 37: //down if(!map[playerX][playerY+1][1] > 0){ playerY++; } break; default: break; } } function loadAll(){ //load the game if(loaded == tileDict.length + charDict.length + objectDict.length){ clearInterval(loadTimer); loadTimer = setInterval(gameUpdate,100); } } function drawMap(){ //draw the map (in intervals) var tileH = 25; var tileW = 50; mapX = 80; mapY = 10; for(i=0;i<map.length;i++){ for(j=0;j<map[i].length;j++){ var drawTile= map[i][j][0]; var xpos = (i-j)*tileH + mapX*4.5; var ypos = (i+j)*tileH/2+ mapY*3.0; ctx.drawImage(tileImg[drawTile],xpos,ypos); if(i == playerX && j == playerY){ you = ctx.drawImage(charImg[0],xpos,ypos-(charImg[0].height/2)); } } } } function init(){ //initialise the main functions and even handlers ctx = document.getElementById('main').getContext('2d'); loadImg(); loadTimer = setInterval(loadAll,10); document.onkeydown = checkKeycode; } function gameUpdate() { //update the game, clear canvas etc ctx.clearRect(0,0,904,460); ctx.fillStyle = "rgba(255, 255, 255, 1.0)"; //assign color drawMap(); } </script> </head> <body align="center" style="text-align: center;" onload="init()"> <canvas id="main" width="904" height="465"> <h1 style="color: white; font-size: 24px;">I'll be damned, there be no HTML5 &amp; canvas support on this 'ere electronic machine!<sub>This game, jus' plain ol' won't work!</sub></h1> </canvas> </body> </html>

    Read the article

  • Javascript not working in IE but works in Firefox chrome

    - by user1290528
    So i have the following php page with a java script that gets the total of items based on their quatity, then inputs the total into a text box for each item. In ie the text boxes are being filled with $NaN. While in firefox, chrome the text boxes are filled with the correct values. Any help would be graatly appreciated. <?php echo $_SESSION['SESS_MEMBER_ID']; require_once('auth.php'); ?> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <meta content="text/html; charset=ISO-8859-1" http-equiv="Content-Type"> <title>Breakfast Menu</title> <link href="loginmodule.css" rel="stylesheet" type="text/css"> <script type='text/javascript'> var totalarray=new Array(); var totalarray2= new Array(); var runningtotal = 0; var runningtotal2 = 0; var discount = .2; var discounttotal = 0; var discount1 = 0; runningtotal = runningtotal * 1; runningtotal2 = runningtotal2 * 1; function displayResult(price,init) { var newstring = "quantity"+init; var totstring = "total"+init; var quantity = document.getElementById(newstring).value; var quantity = parseFloat(quantity); var test = price * quantity; var test = test.toFixed(2); document.getElementById(newstring).value = quantity; document.getElementById(totstring).value = "$" + test; totalarray[init] = test; getTotal(); } function getTotal(){ runningtotal = 0; var i=0; for (i=0;i<totalarray.length;i++){ totalarray[i] = totalarray[i] *1; runningtotal = runningtotal + totalarray[i]; discounttotal = totalarray[i] * discount; discounttotal = totalarray[i] - discounttotal; This line is where IE shows its first error document.getElementById('totalcost').value="$" + runningtotal.toFixed(2); } var orderpart1 = document.getElementById('totalcost').value; var orderpart1 = orderpart1.substr(1); var orderpart1 = orderpart1 * 1; var orderpart2 = document.getElementById('totalcost2').value; var orderpart2 = orderpart2.substr(1); var orderpart2 = orderpart2 * 1; var ordertot = orderpart1 + orderpart2; document.getElementById('ordertotal').value ="$"+ ordertot.toFixed(2) } function displayResult2(price2,init2) { var newstring2 = "quantity2"+init2; var totstring2 = "total2"+init2; var quantity2 = document.getElementById(newstring2).value; var quantity2 = parseFloat(quantity2); var test2 = price2 * quantity2; var test2 = test2.toFixed(2); document.getElementById(newstring2).value = quantity2; document.getElementById(totstring2).value = "$" + test2; totalarray2[init2] = test2; getTotal2(); } function getTotal2(){ runningtotal2 = 0; var i=0; for (i=0;i<totalarray2.length;i++){ totalarray2[i] = totalarray2[i] *1; runningtotal2 = runningtotal2+ totalarray2[i]; This is where IE shows its second error document.getElementById('totalcost2').value="$" + runningtotal2.toFixed(2); }//IE Shows Second error here var orderpart1 = document.getElementById('totalcost').value; var orderpart1 = orderpart1.substr(1); var orderpart1 = orderpart1 * 1; var orderpart2 = document.getElementById('totalcost2').value; var orderpart2 = orderpart2.substr(1); var orderpart2 = orderpart2 * 1; var ordertot = orderpart1 + orderpart2; document.getElementById('ordertotal').value ="$"+ ordertot.toFixed(2); } </script> </head> <body> <?php include("newnew.php"); ?> <td style="vertical-align: top; width: 80%; height:80%;"><br> <div style="text-align: center;"> <form action="testplaceorder.php" method="post" onSubmit="return confirm('Are you sure?');"> <h4>Employee Breakfast Order Form</h4> <h1 align="left">Breakfest Foods</h1> <table border='0' cellpadding='0' cellspacing='0'> <tr> <td> <table width="100%" border="1"> <tr> <th>Item&nbsp&nbsp&nbsp&nbsp&nbsp</th> <th>Price&nbsp&nbsp&nbsp&nbsp&nbsp </th> <th>Quantity&nbsp&nbsp&nbsp&nbsp&nbsp</th> <th>Total&nbsp&nbsp&nbsp&nbsp&nbsp</th> </tr> <?php mysql_connect("localhost", "seniorproject", "farmingdale123") or die(mysql_error()); mysql_select_db("fsenior") or die(mysql_error()); $result = mysql_query("SELECT name, price,foodid FROM Food where foodtype='br'") or die(mysql_error()); $init = 0; while(list($name, $price, $brId) = mysql_fetch_row($result)) { echo "<tr> <td>$name</td> <td>\$$price</td> <td><select name='quantity$init' id='quantity$init' onchange='displayResult($price,$init)'><option>0</option><option>1</option><option>2</option><option>3</option><option>4</option><option>5</option><option>6</option><option>7</option><option>8</option><option>9</option></td> <td><input name='total$init' type='text' id='total$init' readonly='readonly' value='\$0.00'></td> </tr>" ; echo "<script type='text/javascript'>displayResult($price,$init);</script>"; $foodname = "'SESS_FOODNAME_" . $init . "'"; $foodid = "'SESS_FOODID_" . $init."'"; $_SESSION[$foodname] = $name; $_SESSION[$foodid] = $brId; $init = $init+1; } $_SESSION['SESS_INIT'] = $init; ?> <tr> <td></td> <td></td> <td>Total Cost</td> <td><input name='totalcost' type='text' id='totalcost' readonly='readonly' value='$0.00'></td> </tr> <tr><td></td><td></td><td>Discount</td><td><input name='discountvalue1' id ='discountvalue1' type='text' readonly='readonly' value='20%'></td> </tr> <tr><td></td><td></td><td>Total After Discount</td><td><input name='discounttotal1' id ='discounttotal1' type='text' readonly='readonly' value='$0.00'></td></tr> </table> <tr> <td><br></td> </tr> </table> <h1 align="left">Breakfest Drinks</h1> <table border='0' cellpadding='0' cellspacing='0'> <tr> <td> <table width="100%" border="1"> <tr> <th>Item&nbsp&nbsp&nbsp&nbsp&nbsp</th> <th>Price&nbsp&nbsp&nbsp&nbsp&nbsp </th> <th>Quantity&nbsp&nbsp&nbsp&nbsp&nbsp</th> <th>Total&nbsp&nbsp&nbsp&nbsp&nbsp</th> </tr> <?php mysql_connect("localhost", "****", "***") or die(mysql_error()); mysql_select_db("fsenior") or die(mysql_error()); $result2 = mysql_query("SELECT drinkname, price,drinkid FROM Drinks where drinktype='br'") or die(mysql_error()); $init2 = 0; while(list($name2, $price2, $brId2) = mysql_fetch_row($result2)) { echo "<tr> <td>$name2</td> <td>\$$price2</td> <td><select name='quantity2$init2' id='quantity2$init2' onchange='displayResult2($price2,$init2)'><option>0</option><option>1</option><option>2</option><option>3</option><option>4</option><option>5</option><option>6</option><option>7</option><option>8</option><option>9</option></td> <td><input name='total2$init2' type='text' id='total2$init2' readonly='readonly' value='\$0.00'></td> </tr>" ; echo "<script type='text/javascript'>displayResult2($price2,$init2);</script>"; $drinkname = "'SESS_DRINKNAME_" . $init2 . "'"; $drinkid = "'SESS_DRINKID_" . $init2."'"; $_SESSION[$drinkname] = $name2; $_SESSION[$drinkid] = $brId2; $init2 = $init2+1; } $_SESSION['SESS_INIT2'] = $init2; ?> <tr> <td></td> <td></td> <td>Total Cost</td> <td><input name='totalcost2' type='text' id='totalcost2' readonly='readonly' value='$0.00'></td> </tr> </table> <tr> <td><br></td> </tr> </table> <table border="2"> <tr><td>Total Order Cost:</td><td> <?php echo "<input name='ordertotal' type='text' id='ordertotal' readonly='readonly' value='\$0.00'></td></table>"; ?> <p align="left"><input type='submit' name='submit' value='Submit'/></p> </form> </div></td> </tr> </tbody> </table></td> </tr> </tbody> </table> </body> </html>

    Read the article

  • Reading xml document in firefox

    - by Searock
    I am trying to read customers.xml using javascript. My professor has taught us to read xml using `ActiveXObjectand he has given us an assignment to create a sample login page which checks username and password by reading customers.xml. I am trying to use DOMParser so that it works with firefox. But when I click on Login button I get this error. Error: syntax error Source File: file:///C:/Users/Searock/Desktop/home/project/project/login.html Line: 1, Column: 1 Source Code: customers.xml Here's my code. login.js var xmlDoc = 0; function checkUser() { var user = document.login.txtLogin.value; var pass = document.login.txtPass.value; //xmlDoc = new ActiveXObject("Microsoft.XMLDOM"); /* xmlDoc = document.implementation.createDocument("","",null); xmlDoc.async = "false"; xmlDoc.onreadystatechange = redirectUser; xmlDoc.load("customers.xml"); */ var parser = new DOMParser(); xmlDoc = parser.parseFromString("customers.xml", "text/xml"); alert(xmlDoc.documentElement.nodeName); xmlDoc.async = "false"; xmlDoc.onreadystatechange = redirectUser; } function redirectUser() { alert(''); var user = document.login.txtLogin.value; var pass = document.login.txtPass.value; var log = 0; if(xmlDoc.readyState == 4) { xmlObj = xmlDoc.documentElement; var len = xmlObj.childNodes.length; for(i = 0; i < len; i++) { var nodeElement = xmlObj.childNodes[i]; var userXml = nodeElement.childNodes[0].firstChild.nodeValue; var passXml = nodeElement.childNodes[1].firstChild.nodeValue; var idXML = nodeElement.attributes[0].value if(userXml == user && passXml == pass) { log = 1; document.cookie = escape(idXML); document.login.submit(); } } } if(log == 0) { var divErr = document.getElementById('Error'); divErr.innerHTML = "<b>Login Failed</b>"; } } customers.xml <?xml version="1.0" encoding="UTF-8"?> <customers> <customer custid="CU101"> <user>jack</user> <pwd>PW101</pwd> <email>[email protected]</email> </customer> <customer custid="CU102"> <user>jill</user> <pwd>PW102</pwd> <email>[email protected]</email> </customer> <customer custid="CU103"> <user>john</user> <pwd>PW103</pwd> <email>[email protected]</email> </customer> <customer custid="CU104"> <user>jeff</user> <pwd>PW104</pwd> <email>[email protected]</email> </customer> </customers> I get parsererror message on line alert(xmlDoc.documentElement.nodeName); I don't know what's wrong with my code. Can some one point me in a right direction? Edit : Ok, I found a solution. var xmlDoc = 0; var xhttp = 0; function checkUser() { var user = document.login.txtLogin.value; var pass = document.login.txtPass.value; var err = ""; if(user == "" || pass == "") { if(user == "") { alert("Enter user name"); } if(pass == "") { alert("Enter Password"); } return; } if (window.XMLHttpRequest) { xhttp=new XMLHttpRequest(); } else // IE 5/6 { xhttp=new ActiveXObject("Microsoft.XMLHTTP"); } xhttp.onreadystatechange = redirectUser; xhttp.open("GET","customers.xml",true); xhttp.send(); } function redirectUser() { var log = 2; var user = document.login.txtLogin.value; var pass = document.login.txtPass.value; if (xhttp.readyState == 4) { log = 0; xmlDoc = xhttp.responseXML; var xmlUsers = xmlDoc.getElementsByTagName('user'); var xmlPasswords = xmlDoc.getElementsByTagName('pwd'); var userLen = xmlDoc.getElementsByTagName('customer').length; var xmlCustomers = xmlDoc.getElementsByTagName('customer'); for (var i = 0; i < userLen; i++) { var xmlUser = xmlUsers[i].childNodes[0].nodeValue; var xmlPass = xmlPasswords[i].childNodes[0].nodeValue; var xmlId = xmlCustomers.item(i).attributes[0].nodeValue; if(xmlUser == user && xmlPass == pass) { log = 1; document.cookie = xmlId; document.login.submit(); break; } } } if(log == 0) { alert("Login failed"); } } Thanks.

    Read the article

  • Using R to Analyze G1GC Log Files

    - by user12620111
    Using R to Analyze G1GC Log Files body, td { font-family: sans-serif; background-color: white; font-size: 12px; margin: 8px; } tt, code, pre { font-family: 'DejaVu Sans Mono', 'Droid Sans Mono', 'Lucida Console', Consolas, Monaco, monospace; } h1 { font-size:2.2em; } h2 { font-size:1.8em; } h3 { font-size:1.4em; } h4 { font-size:1.0em; } h5 { font-size:0.9em; } h6 { font-size:0.8em; } a:visited { color: rgb(50%, 0%, 50%); } pre { margin-top: 0; max-width: 95%; border: 1px solid #ccc; white-space: pre-wrap; } pre code { display: block; padding: 0.5em; } code.r, code.cpp { background-color: #F8F8F8; } table, td, th { border: none; } blockquote { color:#666666; margin:0; padding-left: 1em; border-left: 0.5em #EEE solid; } hr { height: 0px; border-bottom: none; border-top-width: thin; border-top-style: dotted; border-top-color: #999999; } @media print { * { background: transparent !important; color: black !important; filter:none !important; -ms-filter: none !important; } body { font-size:12pt; max-width:100%; } a, a:visited { text-decoration: underline; } hr { visibility: hidden; page-break-before: always; } pre, blockquote { padding-right: 1em; page-break-inside: avoid; } tr, img { page-break-inside: avoid; } img { max-width: 100% !important; } @page :left { margin: 15mm 20mm 15mm 10mm; } @page :right { margin: 15mm 10mm 15mm 20mm; } p, h2, h3 { orphans: 3; widows: 3; } h2, h3 { page-break-after: avoid; } } pre .operator, pre .paren { color: rgb(104, 118, 135) } pre .literal { color: rgb(88, 72, 246) } pre .number { color: rgb(0, 0, 205); } pre .comment { color: rgb(76, 136, 107); } pre .keyword { color: rgb(0, 0, 255); } pre .identifier { color: rgb(0, 0, 0); } pre .string { color: rgb(3, 106, 7); } var hljs=new function(){function m(p){return p.replace(/&/gm,"&").replace(/"}while(y.length||w.length){var v=u().splice(0,1)[0];z+=m(x.substr(q,v.offset-q));q=v.offset;if(v.event=="start"){z+=t(v.node);s.push(v.node)}else{if(v.event=="stop"){var p,r=s.length;do{r--;p=s[r];z+=("")}while(p!=v.node);s.splice(r,1);while(r'+M[0]+""}else{r+=M[0]}O=P.lR.lastIndex;M=P.lR.exec(L)}return r+L.substr(O,L.length-O)}function J(L,M){if(M.sL&&e[M.sL]){var r=d(M.sL,L);x+=r.keyword_count;return r.value}else{return F(L,M)}}function I(M,r){var L=M.cN?'':"";if(M.rB){y+=L;M.buffer=""}else{if(M.eB){y+=m(r)+L;M.buffer=""}else{y+=L;M.buffer=r}}D.push(M);A+=M.r}function G(N,M,Q){var R=D[D.length-1];if(Q){y+=J(R.buffer+N,R);return false}var P=q(M,R);if(P){y+=J(R.buffer+N,R);I(P,M);return P.rB}var L=v(D.length-1,M);if(L){var O=R.cN?"":"";if(R.rE){y+=J(R.buffer+N,R)+O}else{if(R.eE){y+=J(R.buffer+N,R)+O+m(M)}else{y+=J(R.buffer+N+M,R)+O}}while(L1){O=D[D.length-2].cN?"":"";y+=O;L--;D.length--}var r=D[D.length-1];D.length--;D[D.length-1].buffer="";if(r.starts){I(r.starts,"")}return R.rE}if(w(M,R)){throw"Illegal"}}var E=e[B];var D=[E.dM];var A=0;var x=0;var y="";try{var s,u=0;E.dM.buffer="";do{s=p(C,u);var t=G(s[0],s[1],s[2]);u+=s[0].length;if(!t){u+=s[1].length}}while(!s[2]);if(D.length1){throw"Illegal"}return{r:A,keyword_count:x,value:y}}catch(H){if(H=="Illegal"){return{r:0,keyword_count:0,value:m(C)}}else{throw H}}}function g(t){var p={keyword_count:0,r:0,value:m(t)};var r=p;for(var q in e){if(!e.hasOwnProperty(q)){continue}var s=d(q,t);s.language=q;if(s.keyword_count+s.rr.keyword_count+r.r){r=s}if(s.keyword_count+s.rp.keyword_count+p.r){r=p;p=s}}if(r.language){p.second_best=r}return p}function i(r,q,p){if(q){r=r.replace(/^((]+|\t)+)/gm,function(t,w,v,u){return w.replace(/\t/g,q)})}if(p){r=r.replace(/\n/g,"")}return r}function n(t,w,r){var x=h(t,r);var v=a(t);var y,s;if(v){y=d(v,x)}else{return}var q=c(t);if(q.length){s=document.createElement("pre");s.innerHTML=y.value;y.value=k(q,c(s),x)}y.value=i(y.value,w,r);var u=t.className;if(!u.match("(\\s|^)(language-)?"+v+"(\\s|$)")){u=u?(u+" "+v):v}if(/MSIE [678]/.test(navigator.userAgent)&&t.tagName=="CODE"&&t.parentNode.tagName=="PRE"){s=t.parentNode;var p=document.createElement("div");p.innerHTML=""+y.value+"";t=p.firstChild.firstChild;p.firstChild.cN=s.cN;s.parentNode.replaceChild(p.firstChild,s)}else{t.innerHTML=y.value}t.className=u;t.result={language:v,kw:y.keyword_count,re:y.r};if(y.second_best){t.second_best={language:y.second_best.language,kw:y.second_best.keyword_count,re:y.second_best.r}}}function o(){if(o.called){return}o.called=true;var r=document.getElementsByTagName("pre");for(var p=0;p|=||=||=|\\?|\\[|\\{|\\(|\\^|\\^=|\\||\\|=|\\|\\||~";this.ER="(?![\\s\\S])";this.BE={b:"\\\\.",r:0};this.ASM={cN:"string",b:"'",e:"'",i:"\\n",c:[this.BE],r:0};this.QSM={cN:"string",b:'"',e:'"',i:"\\n",c:[this.BE],r:0};this.CLCM={cN:"comment",b:"//",e:"$"};this.CBLCLM={cN:"comment",b:"/\\*",e:"\\*/"};this.HCM={cN:"comment",b:"#",e:"$"};this.NM={cN:"number",b:this.NR,r:0};this.CNM={cN:"number",b:this.CNR,r:0};this.BNM={cN:"number",b:this.BNR,r:0};this.inherit=function(r,s){var p={};for(var q in r){p[q]=r[q]}if(s){for(var q in s){p[q]=s[q]}}return p}}();hljs.LANGUAGES.cpp=function(){var a={keyword:{"false":1,"int":1,"float":1,"while":1,"private":1,"char":1,"catch":1,"export":1,virtual:1,operator:2,sizeof:2,dynamic_cast:2,typedef:2,const_cast:2,"const":1,struct:1,"for":1,static_cast:2,union:1,namespace:1,unsigned:1,"long":1,"throw":1,"volatile":2,"static":1,"protected":1,bool:1,template:1,mutable:1,"if":1,"public":1,friend:2,"do":1,"return":1,"goto":1,auto:1,"void":2,"enum":1,"else":1,"break":1,"new":1,extern:1,using:1,"true":1,"class":1,asm:1,"case":1,typeid:1,"short":1,reinterpret_cast:2,"default":1,"double":1,register:1,explicit:1,signed:1,typename:1,"try":1,"this":1,"switch":1,"continue":1,wchar_t:1,inline:1,"delete":1,alignof:1,char16_t:1,char32_t:1,constexpr:1,decltype:1,noexcept:1,nullptr:1,static_assert:1,thread_local:1,restrict:1,_Bool:1,complex:1},built_in:{std:1,string:1,cin:1,cout:1,cerr:1,clog:1,stringstream:1,istringstream:1,ostringstream:1,auto_ptr:1,deque:1,list:1,queue:1,stack:1,vector:1,map:1,set:1,bitset:1,multiset:1,multimap:1,unordered_set:1,unordered_map:1,unordered_multiset:1,unordered_multimap:1,array:1,shared_ptr:1}};return{dM:{k:a,i:"",k:a,r:10,c:["self"]}]}}}();hljs.LANGUAGES.r={dM:{c:[hljs.HCM,{cN:"number",b:"\\b0[xX][0-9a-fA-F]+[Li]?\\b",e:hljs.IMMEDIATE_RE,r:0},{cN:"number",b:"\\b\\d+(?:[eE][+\\-]?\\d*)?L\\b",e:hljs.IMMEDIATE_RE,r:0},{cN:"number",b:"\\b\\d+\\.(?!\\d)(?:i\\b)?",e:hljs.IMMEDIATE_RE,r:1},{cN:"number",b:"\\b\\d+(?:\\.\\d*)?(?:[eE][+\\-]?\\d*)?i?\\b",e:hljs.IMMEDIATE_RE,r:0},{cN:"number",b:"\\.\\d+(?:[eE][+\\-]?\\d*)?i?\\b",e:hljs.IMMEDIATE_RE,r:1},{cN:"keyword",b:"(?:tryCatch|library|setGeneric|setGroupGeneric)\\b",e:hljs.IMMEDIATE_RE,r:10},{cN:"keyword",b:"\\.\\.\\.",e:hljs.IMMEDIATE_RE,r:10},{cN:"keyword",b:"\\.\\.\\d+(?![\\w.])",e:hljs.IMMEDIATE_RE,r:10},{cN:"keyword",b:"\\b(?:function)",e:hljs.IMMEDIATE_RE,r:2},{cN:"keyword",b:"(?:if|in|break|next|repeat|else|for|return|switch|while|try|stop|warning|require|attach|detach|source|setMethod|setClass)\\b",e:hljs.IMMEDIATE_RE,r:1},{cN:"literal",b:"(?:NA|NA_integer_|NA_real_|NA_character_|NA_complex_)\\b",e:hljs.IMMEDIATE_RE,r:10},{cN:"literal",b:"(?:NULL|TRUE|FALSE|T|F|Inf|NaN)\\b",e:hljs.IMMEDIATE_RE,r:1},{cN:"identifier",b:"[a-zA-Z.][a-zA-Z0-9._]*\\b",e:hljs.IMMEDIATE_RE,r:0},{cN:"operator",b:"|=||   Using R to Analyze G1GC Log Files   Using R to Analyze G1GC Log Files Introduction Working in Oracle Platform Integration gives an engineer opportunities to work on a wide array of technologies. My team’s goal is to make Oracle applications run best on the Solaris/SPARC platform. When looking for bottlenecks in a modern applications, one needs to be aware of not only how the CPUs and operating system are executing, but also network, storage, and in some cases, the Java Virtual Machine. I was recently presented with about 1.5 GB of Java Garbage First Garbage Collector log file data. If you’re not familiar with the subject, you might want to review Garbage First Garbage Collector Tuning by Monica Beckwith. The customer had been running Java HotSpot 1.6.0_31 to host a web application server. I was told that the Solaris/SPARC server was running a Java process launched using a commmand line that included the following flags: -d64 -Xms9g -Xmx9g -XX:+UseG1GC -XX:MaxGCPauseMillis=200 -XX:InitiatingHeapOccupancyPercent=80 -XX:PermSize=256m -XX:MaxPermSize=256m -XX:+PrintGC -XX:+PrintGCTimeStamps -XX:+PrintHeapAtGC -XX:+PrintGCDateStamps -XX:+PrintFlagsFinal -XX:+DisableExplicitGC -XX:+UnlockExperimentalVMOptions -XX:ParallelGCThreads=8 Several sources on the internet indicate that if I were to print out the 1.5 GB of log files, it would require enough paper to fill the bed of a pick up truck. Of course, it would be fruitless to try to scan the log files by hand. Tools will be required to summarize the contents of the log files. Others have encountered large Java garbage collection log files. There are existing tools to analyze the log files: IBM’s GC toolkit The chewiebug GCViewer gchisto HPjmeter Instead of using one of the other tools listed, I decide to parse the log files with standard Unix tools, and analyze the data with R. Data Cleansing The log files arrived in two different formats. I guess that the difference is that one set of log files was generated using a more verbose option, maybe -XX:+PrintHeapAtGC, and the other set of log files was generated without that option. Format 1 In some of the log files, the log files with the less verbose format, a single trace, i.e. the report of a singe garbage collection event, looks like this: {Heap before GC invocations=12280 (full 61): garbage-first heap total 9437184K, used 7499918K [0xfffffffd00000000, 0xffffffff40000000, 0xffffffff40000000) region size 4096K, 1 young (4096K), 0 survivors (0K) compacting perm gen total 262144K, used 144077K [0xffffffff40000000, 0xffffffff50000000, 0xffffffff50000000) the space 262144K, 54% used [0xffffffff40000000, 0xffffffff48cb3758, 0xffffffff48cb3800, 0xffffffff50000000) No shared spaces configured. 2014-05-14T07:24:00.988-0700: 60586.353: [GC pause (young) 7324M->7320M(9216M), 0.1567265 secs] Heap after GC invocations=12281 (full 61): garbage-first heap total 9437184K, used 7496533K [0xfffffffd00000000, 0xffffffff40000000, 0xffffffff40000000) region size 4096K, 0 young (0K), 0 survivors (0K) compacting perm gen total 262144K, used 144077K [0xffffffff40000000, 0xffffffff50000000, 0xffffffff50000000) the space 262144K, 54% used [0xffffffff40000000, 0xffffffff48cb3758, 0xffffffff48cb3800, 0xffffffff50000000) No shared spaces configured. } A simple grep can be used to extract a summary: $ grep "\[ GC pause (young" g1gc.log 2014-05-13T13:24:35.091-0700: 3.109: [GC pause (young) 20M->5029K(9216M), 0.0146328 secs] 2014-05-13T13:24:35.440-0700: 3.459: [GC pause (young) 9125K->6077K(9216M), 0.0086723 secs] 2014-05-13T13:24:37.581-0700: 5.599: [GC pause (young) 25M->8470K(9216M), 0.0203820 secs] 2014-05-13T13:24:42.686-0700: 10.704: [GC pause (young) 44M->15M(9216M), 0.0288848 secs] 2014-05-13T13:24:48.941-0700: 16.958: [GC pause (young) 51M->20M(9216M), 0.0491244 secs] 2014-05-13T13:24:56.049-0700: 24.066: [GC pause (young) 92M->26M(9216M), 0.0525368 secs] 2014-05-13T13:25:34.368-0700: 62.383: [GC pause (young) 602M->68M(9216M), 0.1721173 secs] But that format wasn't easily read into R, so I needed to be a bit more tricky. I used the following Unix command to create a summary file that was easy for R to read. $ echo "SecondsSinceLaunch BeforeSize AfterSize TotalSize RealTime" $ grep "\[GC pause (young" g1gc.log | grep -v mark | sed -e 's/[A-SU-z\(\),]/ /g' -e 's/->/ /' -e 's/: / /g' | more SecondsSinceLaunch BeforeSize AfterSize TotalSize RealTime 2014-05-13T13:24:35.091-0700 3.109 20 5029 9216 0.0146328 2014-05-13T13:24:35.440-0700 3.459 9125 6077 9216 0.0086723 2014-05-13T13:24:37.581-0700 5.599 25 8470 9216 0.0203820 2014-05-13T13:24:42.686-0700 10.704 44 15 9216 0.0288848 2014-05-13T13:24:48.941-0700 16.958 51 20 9216 0.0491244 2014-05-13T13:24:56.049-0700 24.066 92 26 9216 0.0525368 2014-05-13T13:25:34.368-0700 62.383 602 68 9216 0.1721173 Format 2 In some of the log files, the log files with the more verbose format, a single trace, i.e. the report of a singe garbage collection event, was more complicated than Format 1. Here is a text file with an example of a single G1GC trace in the second format. As you can see, it is quite complicated. It is nice that there is so much information available, but the level of detail can be overwhelming. I wrote this awk script (download) to summarize each trace on a single line. #!/usr/bin/env awk -f BEGIN { printf("SecondsSinceLaunch IncrementalCount FullCount UserTime SysTime RealTime BeforeSize AfterSize TotalSize\n") } ###################### # Save count data from lines that are at the start of each G1GC trace. # Each trace starts out like this: # {Heap before GC invocations=14 (full 0): # garbage-first heap total 9437184K, used 325496K [0xfffffffd00000000, 0xffffffff40000000, 0xffffffff40000000) ###################### /{Heap.*full/{ gsub ( "\\)" , "" ); nf=split($0,a,"="); split(a[2],b," "); getline; if ( match($0, "first") ) { G1GC=1; IncrementalCount=b[1]; FullCount=substr( b[3], 1, length(b[3])-1 ); } else { G1GC=0; } } ###################### # Pull out time stamps that are in lines with this format: # 2014-05-12T14:02:06.025-0700: 94.312: [GC pause (young), 0.08870154 secs] ###################### /GC pause/ { DateTime=$1; SecondsSinceLaunch=substr($2, 1, length($2)-1); } ###################### # Heap sizes are in lines that look like this: # [ 4842M->4838M(9216M)] ###################### /\[ .*]$/ { gsub ( "\\[" , "" ); gsub ( "\ \]" , "" ); gsub ( "->" , " " ); gsub ( "\\( " , " " ); gsub ( "\ \)" , " " ); split($0,a," "); if ( split(a[1],b,"M") > 1 ) {BeforeSize=b[1]*1024;} if ( split(a[1],b,"K") > 1 ) {BeforeSize=b[1];} if ( split(a[2],b,"M") > 1 ) {AfterSize=b[1]*1024;} if ( split(a[2],b,"K") > 1 ) {AfterSize=b[1];} if ( split(a[3],b,"M") > 1 ) {TotalSize=b[1]*1024;} if ( split(a[3],b,"K") > 1 ) {TotalSize=b[1];} } ###################### # Emit an output line when you find input that looks like this: # [Times: user=1.41 sys=0.08, real=0.24 secs] ###################### /\[Times/ { if (G1GC==1) { gsub ( "," , "" ); split($2,a,"="); UserTime=a[2]; split($3,a,"="); SysTime=a[2]; split($4,a,"="); RealTime=a[2]; print DateTime,SecondsSinceLaunch,IncrementalCount,FullCount,UserTime,SysTime,RealTime,BeforeSize,AfterSize,TotalSize; G1GC=0; } } The resulting summary is about 25X smaller that the original file, but still difficult for a human to digest. SecondsSinceLaunch IncrementalCount FullCount UserTime SysTime RealTime BeforeSize AfterSize TotalSize ... 2014-05-12T18:36:34.669-0700: 3985.744 561 0 0.57 0.06 0.16 1724416 1720320 9437184 2014-05-12T18:36:34.839-0700: 3985.914 562 0 0.51 0.06 0.19 1724416 1720320 9437184 2014-05-12T18:36:35.069-0700: 3986.144 563 0 0.60 0.04 0.27 1724416 1721344 9437184 2014-05-12T18:36:35.354-0700: 3986.429 564 0 0.33 0.04 0.09 1725440 1722368 9437184 2014-05-12T18:36:35.545-0700: 3986.620 565 0 0.58 0.04 0.17 1726464 1722368 9437184 2014-05-12T18:36:35.726-0700: 3986.801 566 0 0.43 0.05 0.12 1726464 1722368 9437184 2014-05-12T18:36:35.856-0700: 3986.930 567 0 0.30 0.04 0.07 1726464 1723392 9437184 2014-05-12T18:36:35.947-0700: 3987.023 568 0 0.61 0.04 0.26 1727488 1723392 9437184 2014-05-12T18:36:36.228-0700: 3987.302 569 0 0.46 0.04 0.16 1731584 1724416 9437184 Reading the Data into R Once the GC log data had been cleansed, either by processing the first format with the shell script, or by processing the second format with the awk script, it was easy to read the data into R. g1gc.df = read.csv("summary.txt", row.names = NULL, stringsAsFactors=FALSE,sep="") str(g1gc.df) ## 'data.frame': 8307 obs. of 10 variables: ## $ row.names : chr "2014-05-12T14:00:32.868-0700:" "2014-05-12T14:00:33.179-0700:" "2014-05-12T14:00:33.677-0700:" "2014-05-12T14:00:35.538-0700:" ... ## $ SecondsSinceLaunch: num 1.16 1.47 1.97 3.83 6.1 ... ## $ IncrementalCount : int 0 1 2 3 4 5 6 7 8 9 ... ## $ FullCount : int 0 0 0 0 0 0 0 0 0 0 ... ## $ UserTime : num 0.11 0.05 0.04 0.21 0.08 0.26 0.31 0.33 0.34 0.56 ... ## $ SysTime : num 0.04 0.01 0.01 0.05 0.01 0.06 0.07 0.06 0.07 0.09 ... ## $ RealTime : num 0.02 0.02 0.01 0.04 0.02 0.04 0.05 0.04 0.04 0.06 ... ## $ BeforeSize : int 8192 5496 5768 22528 24576 43008 34816 53248 55296 93184 ... ## $ AfterSize : int 1400 1672 2557 4907 7072 14336 16384 18432 19456 21504 ... ## $ TotalSize : int 9437184 9437184 9437184 9437184 9437184 9437184 9437184 9437184 9437184 9437184 ... head(g1gc.df) ## row.names SecondsSinceLaunch IncrementalCount ## 1 2014-05-12T14:00:32.868-0700: 1.161 0 ## 2 2014-05-12T14:00:33.179-0700: 1.472 1 ## 3 2014-05-12T14:00:33.677-0700: 1.969 2 ## 4 2014-05-12T14:00:35.538-0700: 3.830 3 ## 5 2014-05-12T14:00:37.811-0700: 6.103 4 ## 6 2014-05-12T14:00:41.428-0700: 9.720 5 ## FullCount UserTime SysTime RealTime BeforeSize AfterSize TotalSize ## 1 0 0.11 0.04 0.02 8192 1400 9437184 ## 2 0 0.05 0.01 0.02 5496 1672 9437184 ## 3 0 0.04 0.01 0.01 5768 2557 9437184 ## 4 0 0.21 0.05 0.04 22528 4907 9437184 ## 5 0 0.08 0.01 0.02 24576 7072 9437184 ## 6 0 0.26 0.06 0.04 43008 14336 9437184 Basic Statistics Once the data has been read into R, simple statistics are very easy to generate. All of the numbers from high school statistics are available via simple commands. For example, generate a summary of every column: summary(g1gc.df) ## row.names SecondsSinceLaunch IncrementalCount FullCount ## Length:8307 Min. : 1 Min. : 0 Min. : 0.0 ## Class :character 1st Qu.: 9977 1st Qu.:2048 1st Qu.: 0.0 ## Mode :character Median :12855 Median :4136 Median : 12.0 ## Mean :12527 Mean :4156 Mean : 31.6 ## 3rd Qu.:15758 3rd Qu.:6262 3rd Qu.: 61.0 ## Max. :55484 Max. :8391 Max. :113.0 ## UserTime SysTime RealTime BeforeSize ## Min. :0.040 Min. :0.0000 Min. : 0.0 Min. : 5476 ## 1st Qu.:0.470 1st Qu.:0.0300 1st Qu.: 0.1 1st Qu.:5137920 ## Median :0.620 Median :0.0300 Median : 0.1 Median :6574080 ## Mean :0.751 Mean :0.0355 Mean : 0.3 Mean :5841855 ## 3rd Qu.:0.920 3rd Qu.:0.0400 3rd Qu.: 0.2 3rd Qu.:7084032 ## Max. :3.370 Max. :1.5600 Max. :488.1 Max. :8696832 ## AfterSize TotalSize ## Min. : 1380 Min. :9437184 ## 1st Qu.:5002752 1st Qu.:9437184 ## Median :6559744 Median :9437184 ## Mean :5785454 Mean :9437184 ## 3rd Qu.:7054336 3rd Qu.:9437184 ## Max. :8482816 Max. :9437184 Q: What is the total amount of User CPU time spent in garbage collection? sum(g1gc.df$UserTime) ## [1] 6236 As you can see, less than two hours of CPU time was spent in garbage collection. Is that too much? To find the percentage of time spent in garbage collection, divide the number above by total_elapsed_time*CPU_count. In this case, there are a lot of CPU’s and it turns out the the overall amount of CPU time spent in garbage collection isn’t a problem when viewed in isolation. When calculating rates, i.e. events per unit time, you need to ask yourself if the rate is homogenous across the time period in the log file. Does the log file include spikes of high activity that should be separately analyzed? Averaging in data from nights and weekends with data from business hours may alias problems. If you have a reason to suspect that the garbage collection rates include peaks and valleys that need independent analysis, see the “Time Series” section, below. Q: How much garbage is collected on each pass? The amount of heap space that is recovered per GC pass is surprisingly low: At least one collection didn’t recover any data. (“Min.=0”) 25% of the passes recovered 3MB or less. (“1st Qu.=3072”) Half of the GC passes recovered 4MB or less. (“Median=4096”) The average amount recovered was 56MB. (“Mean=56390”) 75% of the passes recovered 36MB or less. (“3rd Qu.=36860”) At least one pass recovered 2GB. (“Max.=2121000”) g1gc.df$Delta = g1gc.df$BeforeSize - g1gc.df$AfterSize summary(g1gc.df$Delta) ## Min. 1st Qu. Median Mean 3rd Qu. Max. ## 0 3070 4100 56400 36900 2120000 Q: What is the maximum User CPU time for a single collection? The worst garbage collection (“Max.”) is many standard deviations away from the mean. The data appears to be right skewed. summary(g1gc.df$UserTime) ## Min. 1st Qu. Median Mean 3rd Qu. Max. ## 0.040 0.470 0.620 0.751 0.920 3.370 sd(g1gc.df$UserTime) ## [1] 0.3966 Basic Graphics Once the data is in R, it is trivial to plot the data with formats including dot plots, line charts, bar charts (simple, stacked, grouped), pie charts, boxplots, scatter plots histograms, and kernel density plots. Histogram of User CPU Time per Collection I don't think that this graph requires any explanation. hist(g1gc.df$UserTime, main="User CPU Time per Collection", xlab="Seconds", ylab="Frequency") Box plot to identify outliers When the initial data is viewed with a box plot, you can see the one crazy outlier in the real time per GC. Save this data point for future analysis and drop the outlier so that it’s not throwing off our statistics. Now the box plot shows many outliers, which will be examined later, using times series analysis. Notice that the scale of the x-axis changes drastically once the crazy outlier is removed. par(mfrow=c(2,1)) boxplot(g1gc.df$UserTime,g1gc.df$SysTime,g1gc.df$RealTime, main="Box Plot of Time per GC\n(dominated by a crazy outlier)", names=c("usr","sys","elapsed"), xlab="Seconds per GC", ylab="Time (Seconds)", horizontal = TRUE, outcol="red") crazy.outlier.df=g1gc.df[g1gc.df$RealTime > 400,] g1gc.df=g1gc.df[g1gc.df$RealTime < 400,] boxplot(g1gc.df$UserTime,g1gc.df$SysTime,g1gc.df$RealTime, main="Box Plot of Time per GC\n(crazy outlier excluded)", names=c("usr","sys","elapsed"), xlab="Seconds per GC", ylab="Time (Seconds)", horizontal = TRUE, outcol="red") box(which = "outer", lty = "solid") Here is the crazy outlier for future analysis: crazy.outlier.df ## row.names SecondsSinceLaunch IncrementalCount ## 8233 2014-05-12T23:15:43.903-0700: 20741 8316 ## FullCount UserTime SysTime RealTime BeforeSize AfterSize TotalSize ## 8233 112 0.55 0.42 488.1 8381440 8235008 9437184 ## Delta ## 8233 146432 R Time Series Data To analyze the garbage collection as a time series, I’ll use Z’s Ordered Observations (zoo). “zoo is the creator for an S3 class of indexed totally ordered observations which includes irregular time series.” require(zoo) ## Loading required package: zoo ## ## Attaching package: 'zoo' ## ## The following objects are masked from 'package:base': ## ## as.Date, as.Date.numeric head(g1gc.df[,1]) ## [1] "2014-05-12T14:00:32.868-0700:" "2014-05-12T14:00:33.179-0700:" ## [3] "2014-05-12T14:00:33.677-0700:" "2014-05-12T14:00:35.538-0700:" ## [5] "2014-05-12T14:00:37.811-0700:" "2014-05-12T14:00:41.428-0700:" options("digits.secs"=3) times=as.POSIXct( g1gc.df[,1], format="%Y-%m-%dT%H:%M:%OS%z:") g1gc.z = zoo(g1gc.df[,-c(1)], order.by=times) head(g1gc.z) ## SecondsSinceLaunch IncrementalCount FullCount ## 2014-05-12 17:00:32.868 1.161 0 0 ## 2014-05-12 17:00:33.178 1.472 1 0 ## 2014-05-12 17:00:33.677 1.969 2 0 ## 2014-05-12 17:00:35.538 3.830 3 0 ## 2014-05-12 17:00:37.811 6.103 4 0 ## 2014-05-12 17:00:41.427 9.720 5 0 ## UserTime SysTime RealTime BeforeSize AfterSize ## 2014-05-12 17:00:32.868 0.11 0.04 0.02 8192 1400 ## 2014-05-12 17:00:33.178 0.05 0.01 0.02 5496 1672 ## 2014-05-12 17:00:33.677 0.04 0.01 0.01 5768 2557 ## 2014-05-12 17:00:35.538 0.21 0.05 0.04 22528 4907 ## 2014-05-12 17:00:37.811 0.08 0.01 0.02 24576 7072 ## 2014-05-12 17:00:41.427 0.26 0.06 0.04 43008 14336 ## TotalSize Delta ## 2014-05-12 17:00:32.868 9437184 6792 ## 2014-05-12 17:00:33.178 9437184 3824 ## 2014-05-12 17:00:33.677 9437184 3211 ## 2014-05-12 17:00:35.538 9437184 17621 ## 2014-05-12 17:00:37.811 9437184 17504 ## 2014-05-12 17:00:41.427 9437184 28672 Example of Two Benchmark Runs in One Log File The data in the following graph is from a different log file, not the one of primary interest to this article. I’m including this image because it is an example of idle periods followed by busy periods. It would be uninteresting to average the rate of garbage collection over the entire log file period. More interesting would be the rate of garbage collect in the two busy periods. Are they the same or different? Your production data may be similar, for example, bursts when employees return from lunch and idle times on weekend evenings, etc. Once the data is in an R Time Series, you can analyze isolated time windows. Clipping the Time Series data Flashing back to our test case… Viewing the data as a time series is interesting. You can see that the work intensive time period is between 9:00 PM and 3:00 AM. Lets clip the data to the interesting period:     par(mfrow=c(2,1)) plot(g1gc.z$UserTime, type="h", main="User Time per GC\nTime: Complete Log File", xlab="Time of Day", ylab="CPU Seconds per GC", col="#1b9e77") clipped.g1gc.z=window(g1gc.z, start=as.POSIXct("2014-05-12 21:00:00"), end=as.POSIXct("2014-05-13 03:00:00")) plot(clipped.g1gc.z$UserTime, type="h", main="User Time per GC\nTime: Limited to Benchmark Execution", xlab="Time of Day", ylab="CPU Seconds per GC", col="#1b9e77") box(which = "outer", lty = "solid") Cumulative Incremental and Full GC count Here is the cumulative incremental and full GC count. When the line is very steep, it indicates that the GCs are repeating very quickly. Notice that the scale on the Y axis is different for full vs. incremental. plot(clipped.g1gc.z[,c(2:3)], main="Cumulative Incremental and Full GC count", xlab="Time of Day", col="#1b9e77") GC Analysis of Benchmark Execution using Time Series data In the following series of 3 graphs: The “After Size” show the amount of heap space in use after each garbage collection. Many Java objects are still referenced, i.e. alive, during each garbage collection. This may indicate that the application has a memory leak, or may indicate that the application has a very large memory footprint. Typically, an application's memory footprint plateau's in the early stage of execution. One would expect this graph to have a flat top. The steep decline in the heap space may indicate that the application crashed after 2:00. The second graph shows that the outliers in real execution time, discussed above, occur near 2:00. when the Java heap seems to be quite full. The third graph shows that Full GCs are infrequent during the first few hours of execution. The rate of Full GC's, (the slope of the cummulative Full GC line), changes near midnight.   plot(clipped.g1gc.z[,c("AfterSize","RealTime","FullCount")], xlab="Time of Day", col=c("#1b9e77","red","#1b9e77")) GC Analysis of heap recovered Each GC trace includes the amount of heap space in use before and after the individual GC event. During garbage coolection, unreferenced objects are identified, the space holding the unreferenced objects is freed, and thus, the difference in before and after usage indicates how much space has been freed. The following box plot and bar chart both demonstrate the same point - the amount of heap space freed per garbage colloection is surprisingly low. par(mfrow=c(2,1)) boxplot(as.vector(clipped.g1gc.z$Delta), main="Amount of Heap Recovered per GC Pass", xlab="Size in KB", horizontal = TRUE, col="red") hist(as.vector(clipped.g1gc.z$Delta), main="Amount of Heap Recovered per GC Pass", xlab="Size in KB", breaks=100, col="red") box(which = "outer", lty = "solid") This graph is the most interesting. The dark blue area shows how much heap is occupied by referenced Java objects. This represents memory that holds live data. The red fringe at the top shows how much data was recovered after each garbage collection. barplot(clipped.g1gc.z[,c("AfterSize","Delta")], col=c("#7570b3","#e7298a"), xlab="Time of Day", border=NA) legend("topleft", c("Live Objects","Heap Recovered on GC"), fill=c("#7570b3","#e7298a")) box(which = "outer", lty = "solid") When I discuss the data in the log files with the customer, I will ask for an explaination for the large amount of referenced data resident in the Java heap. There are two are posibilities: There is a memory leak and the amount of space required to hold referenced objects will continue to grow, limited only by the maximum heap size. After the maximum heap size is reached, the JVM will throw an “Out of Memory” exception every time that the application tries to allocate a new object. If this is the case, the aplication needs to be debugged to identify why old objects are referenced when they are no longer needed. The application has a legitimate requirement to keep a large amount of data in memory. The customer may want to further increase the maximum heap size. Another possible solution would be to partition the application across multiple cluster nodes, where each node has responsibility for managing a unique subset of the data. Conclusion In conclusion, R is a very powerful tool for the analysis of Java garbage collection log files. The primary difficulty is data cleansing so that information can be read into an R data frame. Once the data has been read into R, a rich set of tools may be used for thorough evaluation.

    Read the article

  • Lighttpd with FastCGI configuration running ViewVC - rewrite problems

    - by 0xC0000022L
    At the moment I am struggling with the configuration of lighttpd together with ViewVC. The configuration was ported from Apache 2.2.x, which is still running on the machine, serving the WebDAV/SVN stuff, being proxied through. Now, the problem I am having appears to be with the rewrite rules and I'm not really sure what I am missing here. Here's my configuration (slightly condensed to keep it concise): var.hgwebfcgi = "/var/www/vcs/bin/hgweb.fcgi" var.viewvcfcgi = "/var/www/vcs/bin/wsgi/viewvc.fcgi" var.viewvcstatic = "/var/www/vcs/templates/docroot" var.vcs_errorlog = "/var/log/lighttpd/error.log" var.vcs_accesslog = "/var/log/lighttpd/access.log" $HTTP["host"] =~ "domain.tld" { $SERVER["socket"] == ":443" { protocol = "https://" ssl.engine = "enable" ssl.pemfile = "/etc/lighttpd/ssl/..." ssl.ca-file = "/etc/lighttpd/ssl/..." ssl.use-sslv2 = "disable" setenv.add-environment = ( "HTTPS" => "on" ) url.rewrite-once += ("^/mercurial$" => "/mercurial/" ) url.rewrite-once += ("^/$" => "/viewvc.fcgi" ) alias.url += ( "/viewvc-static" => var.viewvcstatic ) alias.url += ( "/robots.txt" => var.robots ) alias.url += ( "/favicon.ico" => var.favicon ) alias.url += ( "/mercurial" => var.hgwebfcgi ) alias.url += ( "/viewvc.fcgi" => var.viewvcfcgi ) $HTTP["url"] =~ "^/mercurial" { fastcgi.server += ( ".fcgi" => ( ( "bin-path" => var.hgwebfcgi, "socket" => "/tmp/hgwebdir.sock", "min-procs" => 1, "max-procs" => 5 ) ) ) } else $HTTP["url"] =~ "^/viewvc\.fcgi" { fastcgi.server += ( ".fcgi" => ( ( "bin-path" => var.viewvcfcgi, "socket" => "/tmp/viewvc.sock", "min-procs" => 1, "max-procs" => 5 ) ) ) } expire.url = ( "/viewvc-static" => "access plus 60 days" ) server.errorlog = var.vcs_errorlog accesslog.filename = var.vcs_accesslog } } Now, when I access the domain.tld, I correctly see the index of the repositories. However, when I look at the links for each respective repository (or click them, for that matter), it's of the form https://domain.tld/viewvc.fcgi/reponame instead of the intended https://domain.tld/reponame. What do I have to change/add to achieve this? Do I have to "abuse" the index file mechanism somehow? Goal is to keep the /mercurial alias functional. So far I've tried sifting through the lighttpd book from Packt again, also through the lighttpd documentation, but found nothing that seemed to match the problem.

    Read the article

  • How to deal with MySQL Connector/ODBC error "Can't connect to local MySQL server through socket '/var/lib/mysql/mysql.sock'"

    - by user12653020
    I am sure many users run into a mysterious problem when perfectly working ODBC configurations started failing with errors like: Can't connect to local MySQL server through socket '/var/lib/mysql/mysql.sock' The above error message might be preceded with something like [nxDc[yQ]. At the same time odbc.ini specifies in its DSN different SOCKET=/tmp/mysql.sock or a TCP connection SERVER=<remote_host_or_ip>. The question is, what had happened that the ODBC driver started to ignore the DSN options? The clue lies in the corrupted string [nxDc[yQ], which actually was [UnixODBC][MySQL] with each 2nd symbol removed. This is the case of bad conversion from SQLCHAR to SQLWCHAR. The UnixODBC driver manager took a single-byte character string from the client application and tried to convert it into the wide (multi-byte) characters for the Unicode version of MyODBC driver: Initially the piece of the connection string was represented by 1-byte chars like: [S][E][R][V][E][R][=][m][y][h][o][s][t][;] after the bad conversion to wide chars (commonly 2-byte UTF-16) [SE][RV][ER][=m][yh][os][t;] instead of [S\0][E\0][R\0][V\0][E\0][R\0][=\0][m\0][y\0][h\0][o\0][s\0][t\0][;\0] Naturally, the MyODBC driver could not parse the bad string and tried to use the default connection type (SOCKET) with the default value (/var/lib/mysql/mysql.sock) Now we know what happened, but why it happened? In most cases it happened because of using ODBCManageDataSourcesQ4 utility or its older analog ODBCConfig. When registering ODBC drivers they put lots of additional options and one of these options badly affects the UnixODBC driver manager itself. The solution is simple - remove or comment out the option in odbcinst.ini file (it is empty by default) set for the driver: [MySQL ODBC 5.2.6 Driver] Description    = Driver         = /home/dbs/myodbc526/lib/libmyodbc5w.so Driver64       = /home/dbs/myodbc526/lib/libmyodbc5w.so Setup          = /home/dbs/myodbc526/lib/libmyodbc5S.so Setup64        = /home/dbs/myodbc526/lib/libmyodbc5S.so UsageCount     = 1 CPTimeout      = 0 CPTimeToLive   = 0 IconvEncoding  =  # <--------- remove this line Trace          = TraceFile      = TraceLibrary   = After applying this simple solution (remove the line with IconvEncoding = ) everything came to normal. Prior to removing that line I tried putting different encoding names there, but the result was not good, so I really don't know how to properly use it. Unfortunately, UnixODBC manuals say nothing about it. Therefore, removing this option was the only way to get things done.

    Read the article

< Previous Page | 8 9 10 11 12 13 14 15 16 17 18 19  | Next Page >