Thoughts on the FSF

Aside

I think this really points out my thoughts on the FSF the best.  Not that the FSF is bad in any way, or it doesn’t do useful stuff, but they seem to be living in the past.  I guess perhaps the point here is that if you don’t know what’s out there, and how things are used, it’s impossible to make things better.  It’s like creating software for a problem that you don’t understand, or writing a book.  You must first understand what the rules are, how people use them, and then you can create a better solution.

Nov 07

Thoughts on systemd

So the other day, I had to figure out if udev is still supported without using systemd, since the source trees have been merged, and we’re using Ubuntu at work which doesn’t use systemd. (answer: yes)  This research brought me to this systemd comparison page, detailing the differences between sytemd, Upstart, and SysV.  Not knowing much about init systems(besides Upstart and a little bit of SysV), systemd seems to have a lot of features in it – but as I’m reading these features, I’m wondering: should an init system do all of these things?

There seem to be a lot of things which aren’t particularly useful.  But perhaps they are(as I said, I’m not an expert on init systems).  They seem to be creating a particularly complicated system, and it seems to me that many of the features that they espouse could just as easily be handled by a separate program.  Of course, having a separate program does have its downsides, since it can make the startup logic more obtuse.

Also, I really like how in the ‘Miscellaneous’ table there’s a row for the SCM that is used.  I’m thinking “Who the hell cares?”.

Nov 01

Monitor System DBus

I’m currently writing a program which needs to listen to signals on the system DBus, and I needed a way to monitor the system bus.  I followed the directions here, but I came across a slight problem with that.  It turns out that the solution posted only allows you to listen for things that root sends out.  When I ran my program as an unprivileged user, I didn’t see any output in dbus-monitor, however I would see output if I ran the same program as root.  From what I can tell, the configuration posted will only allow you to see what root is sending on the bus, given that user=”root”.

Fortunately, there’s a simple fix for this:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE busconfig PUBLIC
  "-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN"
  "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">

<busconfig>
  <policy context="default">
    <!-- Allow everything to be sent -->
    <allow send_destination="*" eavesdrop="true"/>
    <!-- Allow everything to be received -->
    <allow eavesdrop="true"/>
  </policy>
</busconfig>

Simply change the policy user to a policy context, and you can now see everything that’s on the bus.

As always, make sure that you remove this config once you’re done testing, otherwise it will be easy to circumvent security mechanisms that are in place.

Sep 03

Good Documentation

I just came across this post on Slashdot on how to create good documentation.  This is a good guide.  Too often, documentation that exists out there is not particularly great, or good at showing you how to do something.  This is the reason that I created my D-Bus tutorial – and I hope that it’s been useful to people.  Similar to how Log4J2 didn’t have excellent documentation – it makes sense once you know how things work, but there isn’t a nice, low-knowledge way to go about this.  In fact, right in the documentation it says:

An understanding of how loggers work in Log4j is critical before trying to configure them. Please reference the Log4j architecture if more information is required. Trying to configure Log4j without understanding those concepts will lead to frustration.

…and that’s about the point at which my eyes glaze over.

I’m not saying that the Log4J2 documentation is horrible, but it could be better and somewhat more structured as Steve Losh said.

Aug 22

Log4J2 Setup

I feel that a decent guide on how exactly Log4J2 is setup is in order, because there isn’t a real clear explanation on Apache’s site. Now Apache, I know you guys make a lot of stuff, but seriously a lot of this stuff is just over-engineered.

Alright, on to the configuration stuff!

Here’s an example config file, with an explanation as to what is going on here(at least as far as I can understand it)

<?xml version="1.0" encoding="UTF-8"?>
<configuration status="OFF">
  <appenders>
    <Console name="Console" target="SYSTEM_OUT">
      <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
    </Console>
    <File name="File" fileName="${sys:logFilename}">
      <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
    </File>
  </appenders>
  <loggers>
    <root level="ERROR">
      <appender-ref ref="Console" />
      <appender-ref ref="File"/>
    </root>
    <logger name="com.rm5248.Logtest2" level="ALL" />
  </loggers>
</configuration>

Okay, let’s start at the very top with the configuration tag:

<configuration status="OFF">

If you change the ‘status’ part of this to a level such as “ALL”, you’ll notice that Log4J2 sends out A LOT of information. As far as I can tell, this is just logging information that is part of Log4J2.

Alright, let’s go on to the appenders. When you create a logger, there are several appenders that you can use to send information to various places. The two appenders that we have here are for the console(i.e. System.out) and a file.

<appenders>
    <Console name="Console" target="SYSTEM_OUT">
      <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
    </Console>
    <File name="File" fileName="${sys:logFilename}">
      <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
    </File>
  </appenders>

The PatternLayout that they have determines how the information will be printed out. For the File appender, there is a fileName property with sys:logFilename. This means that the logger will look for the system property of logFilename. This can be set by either:

  1. passing -DlogFilename=XXX to the program
  2. System.setProperty( “logFilename”, XXX )

If you use option #2, you must also reconfigure the logger as shown in this StackOverflow post.  Fortunately, the patters are in fact well documented.  There are a lot of other appenders out there to append to different things, but we’re not worried about that at the moment.

Okay, now on to the final section: the loggers themselves.

  <loggers>
    <root level="ERROR">
      <appender-ref ref="Console" />
      <appender-ref ref="File"/>
    </root>
    <logger name="com.rm5248.Logtest2" level="ALL" />
  </loggers>

As you can see here, we have a root logger and a specific logger.  The root logger has a level of ERROR, which means that everything descending from the root logger will print out all ERROR messages.  The root logger will also go two places: the Console logger and the File logger.

The second logger besides the root logger is logging just one specific file.  The log level for that file is ALL, which overrides the ERROR log level of the root logger.  Thus, all log messages from that file will be logged.  These messages will also be sent to both the CONSOLE log and FILE log, as those settings are inherited from the root logger.  Let’s say that we want to send those log messages to the FILE, but everything will also go to the CONSOLE. We would do something like this:

    <root level="ERROR">
      <appender-ref ref="Console" />
    </root>
    <logger name="com.rm5248.Logtest2" level="ALL" >
       <appender-ref ref="File" />
    </logger>

Since the more specific logger inherits from the root logger, all log messages from com.rm5248.Logtest2 go to the FILE and the CONSOLE.  There’s more stuff that you can do here with that, but I haven’t really delved into it too deeply.

Anyway, here’s the code that I was using when I was playing around with this.  Hopefully this will help you to get started.

XML Config File:

<?xml version="1.0" encoding="UTF-8"?>
<configuration status="OFF">
  <appenders>
    <Console name="Console" target="SYSTEM_OUT">
      <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
    </Console>
    <File name="File" fileName="${sys:logFilename}">
      <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
    </File>
  </appenders>
  <loggers>
    <root level="ERROR">
      <appender-ref ref="Console" />
      <appender-ref ref="File" />
    </root>
    <logger name="com.rm5248.Logtest2" level="ALL" />
  </loggers>
</configuration>

LogTest.java:

package com.rm5248;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.net.URI;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.core.config.ConfigurationFactory;
import org.apache.logging.log4j.core.config.Configurator;
import org.apache.logging.log4j.core.config.XMLConfigurationFactory;


public class LogTest {

	private static Logger logger = LogManager.getLogger( LogTest.class );

	public static void main( String[] args ){
		File logConfigFile = new File( XML_CONFIG_FILE_GOES_HERE );
		System.setProperty( "logFilename", "filename.log" );		

		try {
			FileInputStream fis = new FileInputStream( logConfigFile );

			XMLConfigurationFactory fc = new XMLConfigurationFactory( );
			fc.getConfiguration(  new ConfigurationFactory.ConfigurationSource( fis ) );

			URI configuration = logConfigFile.toURI();
			Configurator.initialize("config", null, configuration);

			org.apache.logging.log4j.core.LoggerContext ctx =
					(org.apache.logging.log4j.core.LoggerContext) LogManager.getContext( true );
			ctx.reconfigure();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}

		logger.debug( "hi debug" );
		logger.info( "hi info" );
		logger.error( "hi error" );

		Logtest2.doSomething();
	}

}

Logtest2.java:

package com.rm5248;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

public class Logtest2 {
	private static Logger logger = LogManager.getLogger( Logtest2.class );
	
	public static void doSomething(){
		logger.debug( "hello" );
		logger.error( "error?!" );
		logger.warn( "warning" );
		logger.info( "la la la" );
	}
}
Aug 04

What the heck, Discovery?

You guys used to be so good. You had a bunch of interesting shows that really let me learn a lot about the world. And now you do crap like mermaids, and now megalodon shark attacks on boats in South Africa.  WHAT THE FUCK?!  Look, I’m all for being entertained, but when I’m watching Discovery, Animal Planet, heck any channel that is owned by Discovery, I’m not looking for entertainment.  I’m looking to learn.

I think that these shows do have a place in the world.  But when you make shows like these, don’t film them as pseudo-documentaries, or “mockumentaries” as people call them.  They should be about possible things that happen.  You guys should be there to help promote thinking about what is there, and what used to be there.  None of this fake crap that you’re putting out there now – it’s frankly insulting.

I know that you guys make enough money as it is.  This is just retarded that you’re doing something like this.  If you want to do something about megalodon, that’s fine.  Let’s do it in a way that lets people learn about megalodon, like what it could have been like.  Also, I don’t want actors playing biologists or anything, get real biologists out there to tell us this stuff.  You do a great disservice to all of us when there are people pretending to be biologists when they really aren’t.

Also, History Channel, I’m looking at you too.  I don’t really have anything against Pawn Stars or American Pickers, because they can be good shows about showing off items from history.  But when I hear crap like Pawn Stars having an item on the show that is in a museum currently, well, that’s just stupid as well.  Again, not that there’s anything wrong with the show itself per se, but when it’s blatantly obvious that they’re not actually buying or selling anything then we have a bit of an issue here.

TruTV, you’re not so good yourself.  I don’t really watch you anymore.  Except for maybe World’s Dumbest.  That’s actually amusing since it’s not really staged, it’s just people making sarcastic comments and mocking dumb people.

Aug 03

A Great Movie Idea

So here’s an idea for a movie that I just thought up: a comedy movie along the lines of Home Alone, but instead of breaking into somebodies house, they try to break into the Wonka factory to steal the secret recipe for chocolate or something like that.  Then they get into all sorts of wacky hijinks because it’s, you know, the Wonka factory.  You’ve got seltzer that lifts you up to the ceiling, gum that makes you fat, people getting stuck in tubes, the list goes on and on!

May 07

Java Scanner and Input Streams

This just took me a stupid long time to figure out, so I’m leaving it here for future reference.

In Java, the easiest way to read lines is using Scanner.  For work, I had written a quick Linux-only serial port implementation, with which I then took ideas from that for use in my cross-platform JavaSerial library.  What I was doing before was simply using a scanner to look for text coming in on the serial port, and splitting it up based on the lines using the scanner.  This worked fine.

Then I used JavaSerial.  And the Scanner wouldn’t work.

AT ALL.

As it turns out, Scanner doesn’t like using the normal read() method found in InputStream.  It instead uses the read() method which takes in a byte[] array.

If this was documented anyplace in the Javadocs, that would be good.  But it’s not.

UPDATE: 

I’ve figured out what the problem was. According to the Javadocs for the read( byte[], off, len ) method, it will block until it reads the entire length requested, which is stupid.  My implementation reads until either the end is reached OR there is no more data available(using the available() method).  See my implementation here.

Apr 28

C Enums

Enums in C are something special.  They’re not strongly typed at all.  As it’s pointed out, sometimes enums are used for making bit values, which is rather convenient.  However, it would be very good if enums could be strongly typed.  So, here’s my thought on how to make enums in C better.

Enums should be strongly typed.  The following should throw a compile error about assigning an integer to an enum:

enum MyEnum{ Value1 = 0, Value2 = 1 };
enum MyEnum variable = 0;

However, since this is C, casting should be allowed. So you could do this:

enum MyEnum{ Value1 = 0, Value2 = 1 };
enum MyEnum variable = (enum MyEnum)0;

Now about the bitset. I think that the best way to do this is to create a new enum-like type, called bitfield. It would have a syntax nearly itentical to enum, and the compiler could auto-increment the bitfields as well, so that you can ensure bitfields are always good:

bitfield MyBitfield{ Value1 = 0, Value2 = 1, Value3 = 3, Value4 = Value2 | Value3 };

The compiler would then go through and ensure that all bitfields are valid. You could also put more than one bitfield value into a bitfield, and the compiler would ensure that they’re both of the same type. So, this would be valid:

bitfield MyBitfield{ Value1 = 0, Value2 = 1, Value3 = 3, Value4 = Value2 | Value3 };
bitfield variable = Value1;  /* Works */

/* When passing in a method */
void foo( bitfield parameter ){
  if( parameter & Value2 ){
    /* Do something */
  }
}

This would create a much more type-safe form of enums for C. While not backwards-compatible, it’s not a dramatic shift in how enums are used, so it wouldn’t require huge changes.