@@ -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"
@@ -968,7 +973,45 @@ func jsonToValue(i *interpreter, v interface{}) (value, error) {
968973 }
969974}
970975
976+ var (
977+ stackProfileOut * bufio.Writer
978+ stackProfileRatio = 0.01
979+ )
980+
981+ func StartStackProfile () {
982+ var err error
983+
984+ if os .Getenv ("JSONNET_STACK_PROFILE" ) != "" {
985+ stackProfileOutFile , err := os .Create (os .Getenv ("JSONNET_STACK_PROFILE" ))
986+ if err != nil {
987+ log .Fatal ("could not create stack profile: " , err )
988+ }
989+ stackProfileOut = bufio .NewWriter (stackProfileOutFile )
990+ }
991+
992+ if os .Getenv ("JSONNET_STACK_PROFILE_RATIO" ) != "" {
993+ stackProfileRatio , err = strconv .ParseFloat (os .Getenv ("JSONNET_STACK_PROFILE_RATIO" ), 64 )
994+ if err != nil {
995+ log .Fatal ("could not parse stack profile ratio: " , err )
996+ }
997+ }
998+ }
999+
1000+ func StopStackProfile () {
1001+ if stackProfileOut != nil {
1002+ stackProfileOut .Flush ()
1003+ }
1004+ }
1005+
9711006func (i * interpreter ) EvalInCleanEnv (env * environment , ast ast.Node , trimmable bool ) (value , error ) {
1007+ if stackProfileOut != nil && rand .Float64 () < stackProfileRatio {
1008+ stack := []string {}
1009+ for _ , frame := range i .getCurrentStackTrace () {
1010+ stack = append (stack , frame .Loc .String ()+ ":" + frame .Name )
1011+ }
1012+ fmt .Fprintln (stackProfileOut , strings .Join (stack , ";" )+ " 1" )
1013+ }
1014+
9721015 err := i .newCall (* env , trimmable )
9731016 if err != nil {
9741017 return nil , err
0 commit comments