jni: add more logging options (e.g., vmodule)

MultiPart: 2/2
Change-Id: Idf0c3f29cbac03c78b02296796e40feb549f51b8
diff --git a/jni.go b/jni.go
index 2ae5c73..23f0cab 100644
--- a/jni.go
+++ b/jni.go
@@ -53,18 +53,13 @@
 	jCtx := jutil.Object(uintptr(unsafe.Pointer(jContext)))
 	jOpts := jutil.Object(uintptr(unsafe.Pointer(jOptions)))
 
-	level, err := jutil.GetIntOption(env, jOpts, "io.v.v23.LOG_LEVEL")
-	if err != nil {
-		jutil.JThrowV(env, err)
-		return nil
-	}
-	logToStderr, err := jutil.GetBooleanOption(env, jOpts, "io.v.v23.LOG_TO_STDERR")
+	dir, toStderr, level, vmodule, err := loggingOpts(env, jOpts)
 	if err != nil {
 		jutil.JThrowV(env, err)
 		return nil
 	}
 	logger := vlog.NewLogger("jlog")
-	logger.Configure(vlog.OverridePriorConfiguration(true), vlog.Level(level), vlog.LogToStderr(logToStderr))
+	logger.Configure(dir, toStderr, level, vmodule)
 	// Configure the vlog package to use the new logger.
 	vlog.Log = logger
 	// Attach the new logger to the context.
@@ -82,5 +77,33 @@
 	return C.jobject(unsafe.Pointer(jNewCtx))
 }
 
+func loggingOpts(env jutil.Env, jOpts jutil.Object) (dir vlog.LogDir, toStderr vlog.LogToStderr, level vlog.Level, vmodule vlog.ModuleSpec, err error) {
+	var d string
+	d, err = jutil.GetStringOption(env, jOpts, "io.v.v23.LOG_DIR")
+	if err != nil {
+		return
+	}
+	dir = vlog.LogDir(d)
+	var s bool
+	s, err = jutil.GetBooleanOption(env, jOpts, "io.v.v23.LOG_TO_STDERR")
+	if err != nil {
+		return
+	}
+	toStderr = vlog.LogToStderr(s)
+	var l int
+	l, err = jutil.GetIntOption(env, jOpts, "io.v.v23.LOG_VLEVEL")
+	if err != nil {
+		return
+	}
+	level = vlog.Level(l)
+	var m string
+	m, err = jutil.GetStringOption(env, jOpts, "io.v.v23.LOG_VMODULE")
+	if err != nil {
+		return
+	}
+	err = vmodule.Set(m)
+	return
+}
+
 func main() {
 }
diff --git a/jni_android.go b/jni_android.go
index 9e0d6c5..fe97370 100644
--- a/jni_android.go
+++ b/jni_android.go
@@ -25,15 +25,17 @@
 	jCtx := jutil.Object(uintptr(unsafe.Pointer(jContext)))
 	jOpts := jutil.Object(uintptr(unsafe.Pointer(jOptions)))
 
-	level, err := jutil.GetIntOption(env, jOpts, "io.v.v23.LOG_LEVEL")
+	_, _, level, vmodule, err := loggingOpts(env, jOpts)
 	if err != nil {
 		jutil.JThrowV(env, err)
 		return nil
 	}
-	// Send all vlog logs to stderr so that we don't crash on android trying to create a log file.
-	vlog.Log.Configure(vlog.OverridePriorConfiguration(true), vlog.LogToStderr(true), vlog.Level(level))
+	// Setup vlog logger.  We force the logToStderr option so that we don't crash on android trying
+	// to create a log file.
+	vlog.Log.Configure(vlog.OverridePriorConfiguration(true), vlog.LogToStderr(true), level, vmodule)
+
 	// Setup the android logger.
-	logger := NewLogger("alog", level)
+	logger := NewLogger("alog", int(level))
 	// Attach the new logger to the context.
 	ctx, err := jcontext.GoContext(env, jCtx)
 	if err != nil {