We've gone through a few methods where we had printed to the System.out
stream. It's now time to replace them with calls to the BookshelfLogHelper
service.
Next, I'll take two examples and comment on them. The others will be left for you to do on your own:
public MutableBook getBookForEdit(String session, String isbn)
throws BookNotFoundException
{
getLogger().debug(LoggerConstants.LOG_EDIT_BY_ISBN, isbn);
checkSession(session);
MutableBook book = this.inventory.loadBookForEdit(isbn);
debug("Got book for edit: " + book);
return book;
}
The call is logged as a debug message, including the ISBN parameter received by the method. In this implementation, the checkSession()
method also logs session check attempts and failures.
Here a new interface was defined, the LoggerConstants
interface, which holds the pattern strings for the log messages. For example, the declaration for the above constant would be as follows:
public interface LoggerConstants { String LOG_EDIT_BY_ISBN = "LOG_EDIT_BY_ISBN: Get book for edit: [isbn={0}]"; }
Once the full bundle is migrated to use the BookshelfLogHelper
service, this interface would contain the listing of all log messages, along with the expected arguments for each.
Let's go back to the BookshelfServiceImpl
and migrate another method, namely, the addBook()
method:
public void addBook( String sessionId, String isbn, String title, String author, String category, int rating) throws BookAlreadyExistsException, InvalidBookException { getLogger().debug(LoggerConstants.LOG_ADD_BOOK, isbn, title, author, category, rating); checkSession(sessionId); BookInventory inv = lookupBookInventory(); getLogger().debug(LoggerConstants.LOG_CREATE_BOOK, isbn); MutableBook book = inv.createBook(isbn); book.setTitle(title); book.setAuthor(author); book.setCategory(category); book.setRating(rating); getLogger().debug(LoggerConstants.LOG_STORE_BOOK, isbn); inv.storeBook(book); }
It's typical to log something before an operation that may fail to keep a record of its context in the log files. In our case, the operations that may fail are the check for the session, the creation of the book, and its update in the store.
The above log calls have resulted in the following additional constants in the LogConstants
interface:
String LOG_ADD_BOOK = "LOG_ADD_BOOK: Add book: [isbn={0}] [title={1}] "+ "[author={2}] [category={3}] [rating={4}]"; String LOG_CREATE_BOOK = "LOG_CREATE_BOOK: Create new book [isbn={0}]"; String LOG_STORE_BOOK = "LOG_STORE_BOOK: Store book [isbn={0}]";
The above messages can easily be recognized by an external monitoring system and parsed for useful information.
The one last thing to do before we're ready to test our changes is to update the bookshelf-service-tui
dependency on the bookshelf-service
.
Having released the bookshelf-service
bundle with a new version (1.10.0), edit the bookshelf-service-tui
project descriptor and update the dependency version:
<dependency>
<groupId>com.packtpub.felix</groupId>
<artifactId>com.packtpub.felix.bookshelf-service</artifactId>
<version>1.10.0</version>
<type>bundle</type>
<scope>compile</scope>
</dependency>
This shows the downside of having joined service API and implementation in the same bundle for bookshelf-service
. The change we have just made was to the implementation only: releasing a new version of the implementation without changing the interface. However, since both API and implementation are in the same bundle, they are released together.