 	/// By default, it will print to the standard output.
 	@warn_unused_result(message="Did you forget to call `start` on the producer?")
 	public func logEvents(identifier identifier: String = "", events: Set<SignalProducerLoggingEvent> = SignalProducerLoggingEvent.allEvents, fileName: String = #file, functionName: String = #function, lineNumber: Int = #line, logger: EventLogger = defaultEventLog) -> SignalProducer<Value, Error> {
-		
-		let logEvent: String -> Void = { event in
-			logger(identifier: identifier, event: event, fileName: fileName, functionName: functionName, lineNumber: lineNumber)
+		func log<T>(event: SignalProducerLoggingEvent) -> (T -> Void)? {
+			return event.logIfNeeded(events) { event in
+				logger(identifier: identifier, event: event, fileName: fileName, functionName: functionName, lineNumber: lineNumber)
+			}
 		}
-		
-		func log(event: SignalProducerLoggingEvent) -> (() -> Void)? {
-			return events.contains(event) ? { logEvent("\(event.rawValue)") } : nil
-		}
-		
-		func logValue<T>(event: SignalProducerLoggingEvent) -> (T -> Void)? {
-			return events.contains(event) ? { logEvent("\(event.rawValue) \($0)") } : nil
-		}
-		
+
 		return self.on(
 			started: log(.Started),
-			failed: logValue(.Failed),
+			failed: log(.Failed),
 			completed: log(.Completed),
 			interrupted: log(.Interrupted),
 			terminated: log(.Terminated),
 			disposed: log(.Disposed),
-			next: logValue(.Next)
+			next: log(.Next)
 		)
 	}
 }
+
+private protocol LoggingEventType: Hashable, RawRepresentable {}
+extension SignalLoggingEvent: LoggingEventType {}
+extension SignalProducerLoggingEvent: LoggingEventType {}
+
+private extension LoggingEventType {
+	func logIfNeeded<T>(events: Set<Self>, logger: String -> Void) -> (T -> Void)? {
+		guard events.contains(self) else {
+			return nil
+		}
+
+		return { value in
+			if value is Void {
+				logger("\(self.rawValue)")
+			} else {
+				logger("\(self.rawValue) \(value)")
+			}
+		}
+	}
+}

	/// By default, it will print to the standard output.
	@warn_unused_result(message="Did you forget to call `observe` on the signal?")
	public func logEvents(identifier identifier: String = "", events: Set<SignalLoggingEvent> = SignalLoggingEvent.allEvents, fileName: String = #file, functionName: String = #function, lineNumber: Int = #line, logger: EventLogger = defaultEventLog) -> Signal<Value, Error> {
		
		let logEvent: String -> Void = { event in
			logger(identifier: identifier, event: event, fileName: fileName, functionName: functionName, lineNumber: lineNumber)
		}
		
		func log(event: SignalLoggingEvent) -> (() -> Void)? {
			return events.contains(event) ? { logEvent("\(event.rawValue)") } : nil
		}
		
		func logValue<T>(event: SignalLoggingEvent) -> (T -> Void)? {
			return events.contains(event) ? { logEvent("\(event.rawValue) \($0)") } : nil
		}
		
		return self.on(
			failed: logValue(.Failed),
			completed: log(.Completed),
			interrupted: log(.Interrupted),
			terminated: log(.Terminated),
			disposed: log(.Disposed),
			next: logValue(.Next)
		)
	}
}

public enum SignalLoggingEvent: String {
	case Next, Completed, Failed, Terminated, Disposed, Interrupted
	
	public static let allEvents: Set<SignalLoggingEvent> = [
		.Next, .Completed, .Failed, .Terminated, .Disposed, .Interrupted,
	]
}

public enum SignalProducerLoggingEvent: String {
	case Started, Next, Completed, Failed, Terminated, Disposed, Interrupted
	
	public static let allEvents: Set<SignalProducerLoggingEvent> = [
		.Started, .Next, .Completed, .Failed, .Terminated, .Disposed, .Interrupted,
	]
}

private func defaultEventLog(identifier: String, event: String, fileName: String, functionName: String, lineNumber: Int) {
