从sbt插件进行日志记录



我为sbt使用s3解析器插件。

我已更改凭据提供商:

lazy val s3CredentialsProvider = {bucket: String =>
new AWSCredentialsProviderChain(
new EnvironmentVariableCredentialsProvider(),
PropertyFilesCredentialProvider.create(bucket)
)
}

其中CCD_ 1是自定义提供者。

我已经做了以下地方:

  • 我们使用sbt.util.internal添加了一个ConsoleLogger

  • 我们添加了一个System.out.println

我已经发布了这个插件,并一直在另一个插件中使用它。看起来我的插件正在被使用,因为解析器每次都试图使用不同的访问密钥,但我们看不到类中的日志。

当我们在AutoPlugin中有代码时,我们如何添加logging

提供商的代码如下:

导入java.io.{File,FileInputStream,InputStream}导入java.util.Properties

import com.amazonaws.auth.{AWSCredentials, AWSCredentialsProvider, BasicSessionCredentials}
import com.amazonaws.services.securitytoken.AWSSecurityTokenServiceClientBuilder
import com.amazonaws.services.securitytoken.model.{AssumeRoleRequest, AssumeRoleResult, Credentials}
/** Creates a credential provider that reads a `roleArn` property from a file
* and assumes the role using STS.
*
* This is based on https://github.com/frugalmechanic/fm-sbt-s3-resolver/blob/master/src/main/scala/fm/sbt/S3URLHandler.scala#L84
*
* @param file Properties file holding the ROLE_ARN for the project.
*/
class PropertyFilesCredentialProvider(file: File)
extends AWSCredentialsProvider {
private val ROLE_ARN_KEY: String = "roleArn"
private val AWS_REGION: String = "<AWS_REGION>"
protected def getRoleArn: String = {
val is: InputStream = new FileInputStream(file)
try {
val props: Properties = new Properties()
props.load(is)
props.getProperty(ROLE_ARN_KEY)
} finally is.close()
}
def createAWSCredentials(credentials: Credentials): AWSCredentials = {
System.out.println("Retrieved AWS Session Token and Credentials for assuming role")
new BasicSessionCredentials(credentials.getAccessKeyId,
credentials.getSecretAccessKey,
credentials.getSessionToken)
}
def assumeRole(roleArn: String): AssumeRoleResult = {
System.out.println(s"Making a request to AWS STS with the roleArn: $roleArn to assume a role")
val stsClient = AWSSecurityTokenServiceClientBuilder
.standard
.withRegion(AWS_REGION)
.build
val assumeRoleRequest = new AssumeRoleRequest
assumeRoleRequest.setRoleArn(roleArn)
stsClient.assumeRole(assumeRoleRequest)
}
override def getCredentials: AWSCredentials = {
val roleArn = getRoleArn
if (roleArn == null || roleArn == "") {
System.out.println(s"Key of name $ROLE_ARN_KEY was not found in file at ${file.getAbsolutePath}")
return null
}
System.out.println(s"$ROLE_ARN_KEY was read from ${file.getAbsolutePath} successfully")
val assumeRoleResult = assumeRole(roleArn)
System.out.println("Request to assume role using AWS STS successful")
createAWSCredentials(assumeRoleResult.getCredentials)
}
override def refresh(): Unit = {}
}
object PropertyFilesCredentialProvider {
private val DOT_SBT_DIR: File =
new File(System.getProperty("user.home"), ".sbt")
/** Uses a bucket specific propertyfile to read AWS `roleArn` from and provides it
* to the PropertyFilesCredentialProvider.
*
* @param bucket Name of the S3 bucket.
* @return a PropertyFileCredentialProvider
*/
def create(bucket: String): PropertyFilesCredentialProvider = {
val fileName = s".${bucket}_s3credentials"
System.out.println("Using the Property Files Credential Provider")
System.out.println(s"Reading $fileName for AWS Credentials ")
val file: File = new File(DOT_SBT_DIR, fileName)
new PropertyFilesCredentialProvider(file)
}
}

更新

尝试使用streams.value.log失败,错误为:

`value` can only be called on a task within a task definition macro, 
such as :=, +=, ++=, or Def.task.
[error]   val logger = streams.value.log
[error]   

尝试使用ConsoleLogger,它是Logger的一个子类,但在该类中实例化。上面的apply方法是这样调用的:

val logger = sbt.internal.util.ConsoleLogger(System.out)
logger.info("s"Key of name $ROLE_ARN_KEY was not found in file at ${file.getAbsolutePath}"")

在上面的类中。这也没有输出日志。

我创建了两个记录器,一个用于类,另一个用于作为成员的伴随对象,不在扩展PropertyFilesCredentialProvider0的类中。

这是一种将日志记录添加到为AutoPlugin定义的类中的方法

import sbt._
import sbt.Keys._
object TestPlugin extends AutoPlugin {
class SomeClassThatNeedsLogger(logger: Logger) {
def doSomeLogging(): Unit = {
logger.info("It logs")
}
}
object autoImport {
val someClassThatNeedsLoggerHolder = taskKey[SomeClassThatNeedsLogger]("Holds instance of SomeClassThatNeedsLogger")
val runSomeClassThatNeedsLogger = taskKey[Unit]("Runs SomeClassThatNeedsLogger")
}
import autoImport._
override def trigger = allRequirements
override def projectSettings: Seq[Def.Setting[_]] = {
Seq(
someClassThatNeedsLoggerHolder := new SomeClassThatNeedsLogger(streams.value.log),
runSomeClassThatNeedsLogger := someClassThatNeedsLoggerHolder.value.doSomeLogging()
)
}
}

运行会给我们一个日志条目:

> runSomeClassThatNeedsLogger
[info] It logs
[success] Total time: 0 s, completed Feb 6, 2019 9:47:15 AM

关于错误的一些注意事项

value只能在任务定义宏中的任务上调用,
例如:=、+=、++=或Def.task.

此消息告诉您streams.value只能用于任务定义,如someClassThatNeedsLoggerHolder := new SomeClassThatNeedsLogger(streams.value.log)

使用sbt.util.internal 的ConsoleLogger

正如软件包名称所示,这是一个内部软件包,可能会在sbt的下一个版本中发生更改。它不应该在插件定义中使用。

最新更新