Use a logger or roll my own?

  • (2 Pages)
  • +
  • 1
  • 2

27 Replies - 1015 Views - Last Post: 17 June 2013 - 02:48 AM Rate Topic: -----

#1 cfoley  Icon User is online

  • Cabbage
  • member icon

Reputation: 2041
  • View blog
  • Posts: 4,223
  • Joined: 11-December 07

Use a logger or roll my own?

Posted 14 June 2013 - 06:30 PM

I'm writing a list manager (as in project lists and to-do lists). One of the requirements is being able to make a decent effort of merging all the changes that happened since the last sync. A common use case for this would be using the app from my desktop computer and mobile at different times of the day and syncing whenever I bring the two together.

I have chosen to do this by making a DSL (domain specific language). The GUI generates DSL commands and passes them to the core application. Successful commands get written to a file. This means that given two out-of-sync files, it's trivial to find the point in each file where they diverged and merge the rest.

This approach has nice side effects like having an undo history, built-in version control, ease of implementation in other languages (like Objective C for the iPhone), etc.

My question is about writing the DSL calls to file. Do I use a Logger or do I roll my own file-writing classes.

Neither of these options is difficult to implement. On the one hand, it makes sense to use a library that can be made to do what I want. On the other, logging frameworks are intended for diagnostics which is not quite what I want to do here. Log levels don't make sense for this, for example. It's a very specific thing I'm capturing and I may very well want a separate diagnostic log too.

Thoughts and opinions are gratefully received. :)

Is This A Good Question/Topic? 2
  • +

Replies To: Use a logger or roll my own?

#2 macosxnerd101  Icon User is offline

  • Self-Trained Economist
  • member icon




Reputation: 10644
  • View blog
  • Posts: 39,515
  • Joined: 27-December 08

Re: Use a logger or roll my own?

Posted 14 June 2013 - 06:38 PM

I'd probably just roll my own. It's trivial to write to a File, so it's not like this is a major feature. If concurrency is an issue, I might be tempted to look at the Log4j API, which is third party.

To add, I don't do a lot of concurrent programming. Maybe there is something in the standard JDK that will handle concurrency better if it becomes an issue.
Was This Post Helpful? 1
  • +
  • -

#3 jon.kiparsky  Icon User is offline

  • Pancakes!
  • member icon


Reputation: 7869
  • View blog
  • Posts: 13,347
  • Joined: 19-March 11

Re: Use a logger or roll my own?

Posted 14 June 2013 - 08:25 PM

It seems to me that there's not a lot to gain from using a logging framework in this scenario, but if it's convenient to use it, I don't see how it could hurt. I suppose the cautious thing to do would be to ensure that whichever solution you deploy is sufficiently wrapped that you can swap it out in the future. That would make it a cinch to change your mind.
Was This Post Helpful? 1
  • +
  • -

#4 g00se  Icon User is online

  • D.I.C Lover
  • member icon

Reputation: 2773
  • View blog
  • Posts: 11,714
  • Joined: 20-September 08

Re: Use a logger or roll my own?

Posted 15 June 2013 - 02:46 AM

Well of course, since you're a pro, you're already using logging aren't you? ;)

Looking at it that way, it's just another Appender with an appropriate pattern. You're right though, about the use case being different from the normal context of logging. It's a tricky one and i'd probably consider both the functionality required in terms of what we could call 'recording' as opposed to logging, and the functionality that a powerful logging framework such as Logback could offer you, e.g. maybe stuff like log (record?) rotation and compression. Difficult to know exactly without knowing more about your 'recording' requirements.
Was This Post Helpful? 1
  • +
  • -

#5 cfoley  Icon User is online

  • Cabbage
  • member icon

Reputation: 2041
  • View blog
  • Posts: 4,223
  • Joined: 11-December 07

Re: Use a logger or roll my own?

Posted 15 June 2013 - 08:04 AM

Quote

Well of course, since you're a pro, you're already using logging aren't you?


Well, that's the thing. I've never used a logging framework before so I thought this would be a good time to start. Considering the advice above, I think I'll roll my own "Recorder" but also implement logging for diagnostics.

Thanks for all your advice!
Was This Post Helpful? 0
  • +
  • -

#6 g00se  Icon User is online

  • D.I.C Lover
  • member icon

Reputation: 2773
  • View blog
  • Posts: 11,714
  • Joined: 20-September 08

Re: Use a logger or roll my own?

Posted 15 June 2013 - 08:22 AM

http://logback.qos.ch/

Incidentally, the author of the above (also the author of log4j, which is what Logback supersedes) once answered a similar question from me along the lines of your current thinking
Was This Post Helpful? 1
  • +
  • -

#7 cfoley  Icon User is online

  • Cabbage
  • member icon

Reputation: 2041
  • View blog
  • Posts: 4,223
  • Joined: 11-December 07

Re: Use a logger or roll my own?

Posted 15 June 2013 - 08:34 AM

That's nice to know, and thanks for the link. :)

Logging is one of several technologies that I've neglected. Off the top of my head there is logging, build scripts, automated testing other than unit testing, instrumentation, and probably a few others.

With logging, I know there are several frameworks in Java. I'm going to go with java.util.logging for this project and choose a different one for my next project.
Was This Post Helpful? 0
  • +
  • -

#8 g00se  Icon User is online

  • D.I.C Lover
  • member icon

Reputation: 2773
  • View blog
  • Posts: 11,714
  • Joined: 20-September 08

Re: Use a logger or roll my own?

Posted 15 June 2013 - 09:03 AM

Logging is one of the things Java got wrong. What should be in there is probably a Facade (which is what slf4j is about) as well as, or instead of, an implementation. It's tempting to go java.util.logging to avoid extra dependencies, but you might like to look into reasons why you should avoid that temptation (i'm not in command of enough facts to tell you why). If you've got more than one jar in your app, you've got extra dependencies anyway, after all.
Was This Post Helpful? 1
  • +
  • -

#9 cfoley  Icon User is online

  • Cabbage
  • member icon

Reputation: 2041
  • View blog
  • Posts: 4,223
  • Joined: 11-December 07

Re: Use a logger or roll my own?

Posted 15 June 2013 - 11:50 AM

Thanks for the advice. It's advice I had heard before as well but I'm going to go ahead with it anyway. Like I say, I'm going to choose a different logger in each of my next few personal projects. It's all about learning at this point. If java.util.logging turns out to be completely useless, perhaps a painful refactoring will teach me a lesson.

I've now written my recorder and I have a question about testing. Most of my tests write to a StringWriter so I don't have to touch the file system. However, one in particular tests that the recorder appends to the file instead of overwriting it. At the moment, I'm using a temp file set to delete on exit. Does anyone know if this is possible without touching the file system?

As an aside, I learned something cool. \z matches the end of a String which means you can do this:

	public String readEntireFile(File f) throws FileNotFoundException {
		try (Scanner in = new Scanner(f)) {
			in.useDelimiter("\\z");
			return in.next();
		}
	}



It's still long-winded compared to other languages but it does take the pain right out of reading a whole file while preserving the line ends.
Was This Post Helpful? 0
  • +
  • -

#10 g00se  Icon User is online

  • D.I.C Lover
  • member icon

Reputation: 2773
  • View blog
  • Posts: 11,714
  • Joined: 20-September 08

Re: Use a logger or roll my own?

Posted 15 June 2013 - 12:23 PM

Quote

t's still long-winded compared to other languages but it does take the pain right out of reading a whole file while preserving the line ends.
But unfortunately it's not a particularly efficient way of creating a String out of a file. Try this instead

http://technojeeves....-string-in-java

As for 'without touching the filesystem', i'm not quite with you there. What's your motivation?
Was This Post Helpful? 1
  • +
  • -

#11 cfoley  Icon User is online

  • Cabbage
  • member icon

Reputation: 2041
  • View blog
  • Posts: 4,223
  • Joined: 11-December 07

Re: Use a logger or roll my own?

Posted 15 June 2013 - 12:42 PM

Unit tests that interact with the file system, databases, network connections, etc. are usually a sign of poor design of either the test or of the application. Because they access stuff that's not in the codebase, they are brittle and often unportable.

I'm not so puritanical that I would delete the test to adhere to this rule but if anyone knows a way to do this test without reading and writing that would be great.
Was This Post Helpful? 0
  • +
  • -

#12 g00se  Icon User is online

  • D.I.C Lover
  • member icon

Reputation: 2773
  • View blog
  • Posts: 11,714
  • Joined: 20-September 08

Re: Use a logger or roll my own?

Posted 15 June 2013 - 12:46 PM

Well unit test can be just output to the console - i.e. no file system involved at all
Was This Post Helpful? 1
  • +
  • -

#13 cfoley  Icon User is online

  • Cabbage
  • member icon

Reputation: 2041
  • View blog
  • Posts: 4,223
  • Joined: 11-December 07

Re: Use a logger or roll my own?

Posted 15 June 2013 - 12:56 PM

I don't see how that would help in this case.
Was This Post Helpful? 0
  • +
  • -

#14 g00se  Icon User is online

  • D.I.C Lover
  • member icon

Reputation: 2773
  • View blog
  • Posts: 11,714
  • Joined: 20-September 08

Re: Use a logger or roll my own?

Posted 15 June 2013 - 01:21 PM

I'm lost now ...
Was This Post Helpful? 1
  • +
  • -

#15 cfoley  Icon User is online

  • Cabbage
  • member icon

Reputation: 2041
  • View blog
  • Posts: 4,223
  • Joined: 11-December 07

Re: Use a logger or roll my own?

Posted 15 June 2013 - 01:38 PM

Ha ha. OK, here is my test code. It puts some content in a file. Then it records some commands into the same file. The assert makes sure the original content is still in the file alongside the commands. I doubt it is possible to do this without interacting with the file system but I'm just asking to make sure.

	@Test
	public void testAppendToFile() throws IOException {
		File file = tempFile();
		try (PrintWriter out = new PrintWriter(file)) {
			out.println("xxx");
			out.println("yyy");
		}
		try (RecordCommandsToWriter out = new RecordCommandsToWriter(file.toString());)/> {
			out.record("aaa");
			out.record("bbb");
			out.record("ccc");
		}
		assertFileContentsIs(file, "xxx%nyyy%naaa%nbbb%nccc%n");
	}

	private File tempFile() throws IOException {
		String prefix = "JUnit test file - please delete ";
		File result = File.createTempFile(prefix, ".tmp");
		result.deleteOnExit();
		return result;
	}

	private void assertFileContentsIs(File f, String format) throws FileNotFoundException {
		assertFormat(format, readEntireFile(f));
	}

	public String readEntireFile(File f) throws FileNotFoundException {
		try (Scanner in = new Scanner(f)) {
			in.useDelimiter("\\z");
			return in.next();
		}
	}

	public void assertFormat(String format, String actual) {
		String expected = String.format(format);
		assertEquals(expected, actual);
	}


Was This Post Helpful? 0
  • +
  • -

  • (2 Pages)
  • +
  • 1
  • 2