@@ -17,13 +17,18 @@ limitations under the License.
1717package jsonnet
1818
1919import (
20+ "bufio"
2021 "bytes"
2122 "fmt"
2223 "io"
24+ "log"
2325 "math"
26+ "math/rand"
27+ "os"
2428 "reflect"
2529 "sort"
2630 "strconv"
31+ "strings"
2732
2833 "github.com/google/go-jsonnet/ast"
2934 "github.com/google/go-jsonnet/astgen"
@@ -1009,7 +1014,45 @@ func jsonToValue(i *interpreter, v interface{}) (value, error) {
10091014 }
10101015}
10111016
1017+ var (
1018+ stackProfileOut * bufio.Writer
1019+ stackProfileRatio = 0.01
1020+ )
1021+
1022+ func StartStackProfile () {
1023+ var err error
1024+
1025+ if os .Getenv ("JSONNET_STACK_PROFILE" ) != "" {
1026+ stackProfileOutFile , err := os .Create (os .Getenv ("JSONNET_STACK_PROFILE" ))
1027+ if err != nil {
1028+ log .Fatal ("could not create stack profile: " , err )
1029+ }
1030+ stackProfileOut = bufio .NewWriter (stackProfileOutFile )
1031+ }
1032+
1033+ if os .Getenv ("JSONNET_STACK_PROFILE_RATIO" ) != "" {
1034+ stackProfileRatio , err = strconv .ParseFloat (os .Getenv ("JSONNET_STACK_PROFILE_RATIO" ), 64 )
1035+ if err != nil {
1036+ log .Fatal ("could not parse stack profile ratio: " , err )
1037+ }
1038+ }
1039+ }
1040+
1041+ func StopStackProfile () {
1042+ if stackProfileOut != nil {
1043+ stackProfileOut .Flush ()
1044+ }
1045+ }
1046+
10121047func (i * interpreter ) EvalInCleanEnv (env * environment , ast ast.Node , trimmable bool ) (value , error ) {
1048+ if stackProfileOut != nil && rand .Float64 () < stackProfileRatio {
1049+ stack := []string {}
1050+ for _ , frame := range i .getCurrentStackTrace () {
1051+ stack = append (stack , frame .Loc .String ()+ ":" + frame .Name )
1052+ }
1053+ fmt .Fprintln (stackProfileOut , strings .Join (stack , ";" )+ " 1" )
1054+ }
1055+
10131056 err := i .newCall (* env , trimmable )
10141057 if err != nil {
10151058 return nil , err
0 commit comments